Node Express框架

1.概述

Express是一个基于Node平台的web应用开发框架,它提供了一系列强大的特性,帮助创建各种web应用。
下载方式:npm install express

2.特性

  • 提供了方便简洁的路由定义方式
  • 对获取http请求参数进行了简化处理
  • 对模板引擎支撑成都高,方便渲染动态html页面
  • 提供了中间件机制有效控制http请求
  • 拥有大量第三方中间件对功能进行扩展

3.express框架入门

//引入express框架
const express = require('express');
//创建服务器
const app = express();
app.get('/', (req, res) => {
    //send()
    //1.send方法内部会自动检测响应内容的类型
    //2.send方法内部会自动设置http状态码
    //3.send方法会帮助大家自动设置相应内容类型和编码
    res.send('hello.express');
});
app.get('/list',(req,res)=>{
   res.send({name:'张三',age:20});
});

app.listen(3000);
console.log('网站服务器启动成功')

4.中间件

4.1 get.post中间件

中间件就是一堆方法,可以接收客户端发来的请求,可以对请求做出响应,也可以将请求继续交给下一个中间件继续处理
可以针对同一个请求设置多个中间件,对同一个请求进行多次处理。
默认情况下,请求从上到下一次匹配中间件,一旦匹配成功终止匹配。
可以调用next方法将请求的控制权交给下一个中间件,知道遇到结束请求的中间件。

//引入express框架
const express = require('express');
//创建服务器
const app = express();
app.get('/request', (req, res, next) => {
    req.name = '张三';
    next();
});
app.get('/request', (req, res) => {
    res.send(req.name);
});
app.listen(3000);
console.log('网站服务器启动成功')
4.2 app.user中间件

app.use 匹配所有的请求方式,可以直接传入请求处理函数,代表接收所有的请求

//引入express框架
const express = require('express');
//创建服务器
const app = express();
//接受所有请求
app.use((req, res, next) => {
    console.log('请求走了app.use中间件');
    next();
});
//当访问request 接受请求
app.use('/request',(req, res, next) => {
    console.log('请求走了app.use/request中间件');
    next();
});
app.use('/list',(req,res,next)=>{
    res.send('list');
})
app.get('/request', (req, res, next) => {
    req.name = '张三';
    next();
});
app.get('/request', (req, res) => {
    res.send(req.name);
});
app.listen(3000);
console.log('网站服务器启动成功')
4.3 中间间应用
  • 路由保护,登录拦截跳转
  • 网站维护公告
  • 自定义404页面
//引入express框架
const express = require('express');
//创建服务器
const app = express();
//网站公告
// app.use((req, res, next) => {
//     res.send('网站正在维护');
// });
//网站登录
app.use('/admin', (req, res, next) => {
    let isLogin = true;
    if (isLogin) {
        next();
    } else {
        res.send('你还没有登录,不能访问admin这个页面');
    }
});

app.get('/admin', (req, res) => {
    res.status(200).send('你已经登录,可以访问当前页面');
});
//当前客户端相应404
app.use((req,res,next)=>{
    res.status(404).send('当前访问的页面是不存在的');
});
app.listen(3000);
console.log('网站服务器启动成功')//引入express框架
const express = require('express');
//创建服务器
const app = express();
//网站公告
// app.use((req, res, next) => {
//     res.send('网站正在维护');
// });
//网站登录
app.use('/admin', (req, res, next) => {
    let isLogin = true;
    if (isLogin) {
        next();
    } else {
        res.send('你还没有登录,不能访问admin这个页面');
    }
});

app.get('/admin', (req, res) => {
    res.status(200).send('你已经登录,可以访问当前页面');
});
//当前客户端相应404
app.use((req,res,next)=>{
    res.status(404).send('当前访问的页面是不存在的');
});
app.listen(3000);
console.log('网站服务器启动成功')
4.4错误处理中间件

在程序实行的过程中,不可避免的会出现一些无法预料的错误,比如文件读取失败,数据库连接失败,错误处理中间件是一个集中处理错我的地方
当程序出现场错误后,在调用next方法,并将错误信息通过参数传递给next()方法,即可触发错误处理中间件

//引入express框架
const express = require('express');
const fs = require('fs');
//创建服务器
const app = express();
app.get('/index', (req, res, next) => {
    // throw new Error('服务器发生未知错误');
    fs.readFile('./文件清单.txt', 'utf8', (err, result) => {
        if (err != null) {
            next(err);
        } else {
            res.send(result);
        }
    });
    // res.send('程序正常实行');
});
//错误处理中间件四个参数
app.use((err, req, res, next) => {
    res.status(500).send(err.message);
});
app.listen(3000);
console.log('网站服务器启动成功')
4.5 捕获错误

在node.js中,异步api的错误信息都是通过回调函数获取的,支撑Promise对象的异步api发生错误可通过catch方法捕获,异步函数实行如果发生错误要如何捕获错误呢?
tyr catch可以捕获异步函数几其同步代码在实行过程中发生的错误,但是不能捕获其他类型的api发生从错误

//引入express框架
const express = require('express');
const fs = require('fs');
const promisify = require('util').promisify;
const readFile = promisify(fs.readFile);
//创建服务器
const app = express();
app.get('/index', async (req, res, next) => {
    try {
        await readFile('./aaa.js')
    } catch (e) {
        next(e);
    }
});
//错误处理中间件四个参数
app.use((err, req, res, next) => {
    res.status(500).send(err.message);
});
app.listen(3000);
console.log('网站服务器启动成功')

5.Express请求处理

5.1构建模块化路由

app.js

const express = require('express');
const app = express();
//创建路由对象
const home = express.Router();
//为路由对象匹配请求对象
app.use('/home', home);
//创建二级路由
home.get('/index', (req, res) => {
    res.send('欢迎来到博客澳门平台网址大全');
});
app.listen(3000);

home.js

const express = require('express');
const home = express.Router();
home.get('/index', (req, res) => {
    res.send('欢迎来到澳门平台网址大全');
});
module.exports = home;

index.js

const express = require('express');
const admin = express.Router();
admin.get('/index', (req, res) => {
    res.send('欢迎来到管理页面');
});
module.exports = admin;
5.2 GET参数的获取

Express框架中使用req.query即可获取GET参数,框架内部会将GET参数转换为对象并返回。

const express = require('express');
const app = express();
app.get('/index', (req, res) => {
    //获取请求参数    ?name=ithedan&age=30
    res.send(req.query);//{'name':'ithedan','age':''30}
});
app.listen(3000);
5.3 POST参数的获取

Express中接受post请求参数需要借助第三方包 body-parser

const express = require('express');
const app = express();
//获取post 请求参数  需要用到三方模块body-parser
const bodyParser = require('body-parser');
//配置body-parser模板
//extended:false  方法内部使用queyrstring模块处理参数的格式
//extended:true  方法内部使用第三方模块qs处理请求参数的格式
app.use(bodyParser.urlencoded({extended: false}));
app.post('/add', (req, res) => {
    res.send(req.body);
});
app.listen(3000);
5.4 Express路由参数
const express = require('express');
const app = express();
app.get('/index/:id/:name/:age', (req, res) => {
    res.send(req.params);
    //{"id": "21", "name": "ithedan", "age": "32" }
});
app.listen(3000);
localhost:3000/index/21/ithedan/32
5.5 静态资源的处理

通过Express内置的express.static可以方便地托管静态文件,例如img css JavaScript文件等

const express = require('express');
const app = express();
const path = require('path');
//实现静态资源访问功能  static虚拟路径  localhost:3000/static/----
// app.use('/static',express.static(path.join(__dirname, 'public')));
app.use(express.static(path.join(__dirname, 'public')));
app.listen(3000);
http://localhost:3000/css/style.css

6 express-art template 模板引擎

  • 为了是art-template模板引擎能够更好的和express框架配合,模板引擎官方在元art-template模板引擎的基础上封装了express-art-template
  • 使用 npm install art-template express-art-template
const express = require('express');
const app = express();
const path = require('path');
//当渲染后缀为art的模板时,使用express-art-template
app.engine('art', require('express-art-template'));
//设置模板目录
app.set('views', path.join(__dirname, 'views'));
//设置默认后缀
app.set('view engine', 'art');

//模板中可以获取到
app.locals.users = [{
    name: '张三',
    age: 18
}, {
    name: '李四',
    age: 18
}, {
    name: '王五',
    age: 18
},]

app.get('/index', (req, res) => {
    //1 拼接模板路径
    //2 拼接模板后缀
    //3 哪一个模板和哪一个数据进行拼接
    //4 将拼接结果反馈给客户端
    res.render('index', {
        msg: 'message'
    });
});

app.get('/list', (req, res) => {
    res.render('list', {
        msg: 'list page'
    })
});
app.listen(3000);

7。 项目案例初始化

7.1. 建立项目所需文件夹

public 静态资源
model 数据库操作
route 路由
views 模板

7.2. 初始化项目描述文件

npm init -y

7.3. 下载项目所需第三方模块

npm install express mongoose art-template express-art-template

7.4. 创建网站服务器
//引入express模块创建服务器
const express = require('express');
const app = express();
//引入路由模块
const home = require('./route/home');
const admin = require('./route/admin');
//引入express-session
const session = require('express-session');
//引入数据库
require('./model/connect');
//引入path模块用了操作路径
const path = require('path');
//引入body-parser 用来处理post请求参数
const bodyParser = require('body-parser');
//引入art-template
const template = require('art-template');
//引入dateformat模块用来处理日期
const dateFormat = require('dateformat');
//配置session
app.use(session({
    secret: 'cookie_secret',
    resave: true,
    saveUninitialized: true
}));
//告诉express 框架模板所在的位置
app.set('views', path.join(__dirname, 'views'));
//告诉express 模板默认后缀
app.set('view engine', 'art');
//当渲染后缀为art的模板时,所使用的模板引擎是什么
app.engine('art', require('express-art-template'));
//开放静态资源文件
app.use(express.static(path.join(__dirname, 'public')));
//处理post请求参数
app.use(bodyParser.urlencoded({extended: false}));
//登录拦截
app.use('/admin', require('./middleware/loginGuard'));
//关联路由模块 为路由匹配路径
app.use('/home', home);
app.use('/admin', admin);
//错误处理中间件
app.use((err, req, res, next) => {
    console.log(err.message)
    //将字符串对象转换为对象类型
    const result = JSON.parse(err);
    const params = [];
    for (let attr in result) {
        if (attr != 'path') {
            params.push(attr + "=" + result[attr]);
        }
    }
    return res.redirect(`${result.path}?${params.join('&')}`);
});
//向模板内部导入dateFormat变量
template.defaults.imports.dateFormat = dateFormat;

//app监听默认端口80
app.listen(80);
console.log('网站服务器启动成功,通过访问localhost来访问');
7.5. 构建模块化路由
7.6. 构建相关页面模板

推荐阅读更多精彩内容