目录
在express中,路由指的是客户端请求与服务器处理函数之间的映射关系。
express中的路由分为3部分,分别是请求类型,请求URL地址,处理函数,格式如下:
- app.METHOD(URL, FUNCTION)
-
- // 如下例子
- app.get('/user', (req, res) => {
- console.log('get require');
- })
- const express = require('express');
-
- const app = express();
-
- app.get('/', (req, res) => {
-
- res.send('get require');
-
- })
-
- app.post('/', (req, res) => {
-
- res.send('post require');
- })
-
- app.listen('80', () => {
-
- console.log('express server is running at https://127.0.0.1');
- })
每当一个请求到达服务器之后,需要经过路由匹配,匹配成功后,才会调用对应的处理函数。
在匹配时,会按照路由的顺序进行匹配,如果请求类型和请求的URL同时匹配成功,则express会将这次请求,转交给对应的function函数进行处理。
注意:
1. 按照定义的先后顺序进行匹配
2. 请求类型和请求的URL同时匹配成功才会调用对应的处理函数
为了方便对路由进行模块化的管理,express不建议将路由直接挂载到app上,而是推荐将路由抽离为单独的模块。
步骤如下:
1. 创建路由模块对应的js文件
2. 调用express.Router()函数创建路由对象
3. 向路由对象上挂载具体的路由
4. 使用module.exports向外共享路由对象
5. 使用app.use()函数注册路由模块
1. 创建路由模块
- // 1. 导入express模块
- const express = require('express');
-
- // 2. 创建路由对象
- const router = express.Router();
-
- // 3. 挂载获取用户列表路由
- router.get('/user/list', (req, res) => {
- res.send('get user list');
- })
-
- // 4. 挂载添加用户信息路由
- router.post('/user/add', (req, res) => {
- res.send('post user info')
- })
-
- // 5. 导出路由模块
- module.exports = router;
-
2. 注册路由模块

测试get、post请求:


3. 请求路径中挂载统一前缀
于静态资源托管统一挂载前缀的形式类似:
app.use('/xxx', router);
示例:
添加路径前缀,修改后:
用原来但请求路径,请求出错:
需要有对应前缀 /acb 才能请求成功:


当一个请求到达express服务器后,可以连续调用多个中间件对这次请求进行预处理。

1. express中间件本质上是一个函数,这个函数的格式如下:

中间件函数的特点就是第三个参数是个函数next
2. next函数的作用:
next的作用就是保持中间件的流转,让本次函数的处理结果交给下一个中间件

1. 定义基本的中间件
- // 这里所定义的mw,就是指向一个中间件函数
- const mw = function(req, res, next) {
- // 中间件的处理
- // ......
-
- // 必须调用next函数,把流转关系交给下一个中间件
- next();
- }
2. 注册全局生效的中间件
客户端发起的任何请求,到达服务器后,都会触发的中间件,叫做全局生效的中间件。通过钓鱼app.use(中间件函数),即可定义一个全局生效的中间件,示例代码如下:
- const express = require('express');
- const app = express();
- const mw = function(req, res, next) {
- console.log('这是一个最简单的中间件');
- next();
- }
-
- // 注册全局生效的中间件
- app.use(mw);
多个中间件之间,共享一份req和res,基于这样的特性,我们可以在上游的中间件中,统一为req或res对象添加自定义的属性或方法,供下游的中间件或路由进行使用。
- const express = require('express');
- const app = express();
-
- const mw = funtion(req, res, next) {
- const time = Date.now();
- // 为req添加属性
- req.startTime = time;
- next();
- }
- app.use(mw);
-
- app.get('/', (req, res) => {
- // 中间件添加的属性下游中间件或路由可以直接使用
- res.send('get require success '+req.startTime);
- })
-
- app.post('/', (req, res) => {
- // 中间件添加的属性下游中间件或路由可以直接使用
- res.send('get require success '+req.startTime);
- })
-
- app.listen('80', () =>{
- console.log('server running');
- })
- const express = require('express');
- const app = express();
-
- const mw1 = funtion(req, res, next) {
- console.log('调用第一个中间件')
- next();
- }
- const mw2 = funtion(req, res, next) {
- console.log('调用第二个中间件')
- next();
- }
- app.use(mw1);
- app.use(mw2);
-
- app.get('/', (req, res) => {
- res.send('Home page. get')
- })
-
- app.post('/', (req, res) => {
- res.send('Home page. post')
- })
-
- app.listen('80', () =>{
- console.log('server running');
- })
客户端发get/post请求,会按顺序调用第一个中间件,第二个中间件。
不使用app.use()定义的中间件,叫做局部生效的中间件,示例代码如下:
- const mw1 = function(req, res, next){
- console.log('局部生效中间件1');
- next();
- }
-
- const mw2 = function(req, res, next){
- console.log('局部生效中间件2');
- next();
- }
-
- app.get('/user', mw1, (req,res)=>{
- res.send('调用了局部生效中间件')
- })
-
- // 调用多个局部中间件,可以按顺序传入局部中间件函数、
- app.get('/user/more', mw1, mw2, (req,res)=>{
- res.send('调用了局部生效中间件')
- })
-
- // 也可以用数组传入
- // app.get('/user/more', [mw1,mw2], (req,res)=>{
- // res.send('调用了局部生效中间件')
- // })
-
- // 局部中间件不会影响下面这个路由
- app.post('/user', (req, res)=>{
- res.send('没有调用了局部生效中间件')
- })
-
格式:错误级别中间件的function处理函数中,必须有4个形参,形参从前到后分别是(err, req, res,next)
- app.get('/', (req, res)=>{
- throw new Error('error !');
- res.send('xxx');
- })
-
- const mwErr = funtion(err, req, res, next){
- console.log('error!');
- res.send('server error!');
- }
- app.use(mwErr);
注意:错误级别中间件必须注册在所有路由之后
从express4.16.0版本开始,express内置了3个常用的中间件,极大提高了express项目开发的效率和体验:
配置express.json、express.urlencoded中间件:
- app.use(express.json());
- app.use(express.urlencoded({extend:false}));//固定写法
-
- app.post('/user/info',(req, res)=>{
- // 可以打印post请求携带的请求体数据 ,包括json格式和url-encoded格式
- console.log(req.body);
- res.send('ok');
- })
- const parser = require('body-parser');// 引入第三方中间件
- app.use(parser({extend:false}));//固定写法
-
- app.post('/user/info',(req, res)=>{
- // 可以打印post请求携带的请求体数据 ,解析url-encoded数据格式
- console.log(req.body);
- res.send('ok');
- })



