️ NodeJS专栏:Node.js从入门到精通
️ 博主的前端之路(源创征文一等奖作品):前端之行,任重道远(来自大三学长的万字自述)
️ TypeScript知识总结:TypeScript 学习笔记(十万字超详细知识点总结)
个人简介:大三学生,一个不甘平庸的平凡人
你的一键三连是我更新的最大动力❤️!
Express
是一个自身功能极简,完全是由路由和中间件构成一个的 web
开发框架:从本质上来说,一个 Express 应用就是在调用各种中间件。
中间件(Middleware) 是一个函数,它可以访问请求对象(request object (req
)), 响应对象(response object (res
)), 和 web
应用中处于请求-响应
循环流程中的中间件,一般被命名为 next
的变量。
function (req, res, next) {
// 三个参数:req, res, next
console.log('我是一个中间件')
next()
}
中间件的功能包括:
如果当前中间件没有终结请求-响应循环,则必须调用 next()
方法将控制权交给下一个中间件,否则请求就会挂起。
Express
应用可使用如下几种中间件:
使用可选的挂载路径,可在应用级别或路由级别装载中间件。另外,你还可以同时装载一系列中间件函数,从而在一个挂载点上创建一个子中间件栈。
简单来说,应用级中间件就是绑定到应用级别(
app
)上的中间件
应用级中间件使用 app.use()
和 app.METHOD()
绑定到 app
对象 , 其中, METHOD
是需要处理的 HTTP
请求的方法,例如 get
, put
, post
等等,全部小写。例如:
var app = express()
// 不指定挂载路径,则匹配所有路径
app.use(function (req, res, next) {
console.log('无挂载路径的应用级中间件')
next()
})
上边是一个没有挂载路径的应用级中间件,应用的每个请求都会执行该中间件(函数),即用户访问的任何路由都会触发这个函数的执行。
当然我们也可以去指定应用级中间件的挂载路径:
// 指定挂载路径为/home,则只匹配/home
app.use("/home", function (req, res, next) {
console.log("/home路径的应用级中间件");
next();
});
这样就只有匹配到/home
时,上述中间件才会执行。
使用app.METHOD()
挂载多个路由处理函数实际就是指定了挂载路径的应用级中间件的应用:
var app = express()
// isToken是一个中间件
const isToken = (req, res, next) => {
console.log("我相当于是一个中间件!");
next()
};
// getUser是路由的处理函数,并不是中间件
const getUser = (req, res) => {
res.send("匹配 / 路径的get请求");
}
// 使用app.get时指定了/user路径并挂载了isToken中间件,则这里的isToken就相当于是应用级的中间件了
app.get("/user", [isToken], getUser);
在Node.js | 你不知道的 express 路由使用技巧一文中我们提到了一个路由多处理函数的应用:token验证
,我们现在可以使用应用级中间件去改造它一下:
// 不需要token验证
app.get("/login", (req, res) => {
res.send("登录");
});
// 验证token的函数(可插拔,可复用的中间件)
const isToken = (req, res, next) => {
// 验证token是否过期,isVaild代表token是否有效
// 一些操作
const isVaild = true; // 假设验证通过
if (isVaild) {
// 验证通过了就调用next向下执行
console.log("token验证通过");
// 如果想要在回调函数之间传递数据,我们可以选择将数据挂载到res参数上
res.ailjx = "海底烧烤店ai";
next();
} else {
// 返回错误
// 这里res.send后后面的回调函数就不会再执行了
res.send("token验证失败!");
}
};
// app.use用来注册全局的应用中间件,因为JS代码是从上向下执行,所以app.use之后的路由才会受该应用中间件(isToken)的影响,所以需要注意这个app.use的使用地方
app.use(isToken) // app.use之前不受isToken影响
// 只有token有效时才生效的接口
app.get("/home", (req, res) => {
// 返回数据内容
// res.ailjx:获取验证token的函数在res上绑定的数据
res.send("home" + res.ailjx);
});
app.get("/user", (req, res) => {
// 返回数据内容
res.send("user");
});
对比 Node.js | 你不知道的 express 路由使用技巧 一文中的应用,这里我们将isToken
这个中间件在需要token
验证的路由前,不需要token
验证的路由后使用app.use
全局挂载,这样就不需要在/home
和/user
中单独注册添加isToken
了。
路由级中间件和应用级中间件一样,只是它绑定的对象为express.Router()
,在Node.js | 你不知道的 express 路由使用技巧 一文中我们已经详细介绍过,大家可以跳转查看,这里就不再多说啦。
错误处理中间件和其他中间件定义类似,只是要使用 4 个参数 (err
, req
, res
, next
),比普通的中间件多了一个err
参数:
// 错误处理中间件:错误处理程序
app.use(function (err, req, res, next) {
console.error(err);
// status 设置状态码
res.status(404).send("找不到页面!" + err);
});
错误处理中间件顾名思义就是捕获错误并进行处理的中间件,但需要注意的是,它并不会捕获未定义的路由!
const express = require("express");
const app = express();
// 错误处理中间件:错误处理程序
app.use(function (err, req, res, next) {
console.error(err);
// status 设置状态码
res.status(404).send("找不到页面!" + err);
});
app.listen(3000, () => {
console.log("express启动!");
});
上面的代码中我们并没有去定义任何路由,就只是挂载了一个错误处理中间件,现在我们启动该服务器随便访问一个路由:
可以看到我们的错误处理中间件并没有执行,那用户访问未定义的路由时我们怎么去捕获呢?这就可以使用前面说到的应用级中间件:
const express = require("express");
const app = express();
// 定义你的一些路由
// 应用级中间件:捕获未定义的路由
app.use(function (req, res, next) {
// status 设置状态码
res.status(404).send("找不到页面!");
});
app.listen(3000, () => {
console.log("express启动!");
});
另一个问题就是,错误处理中间件在什么情况下才会执行?
当中间件调用next
并向其传入非route
和router
的参数时,会调用错误处理中间件,next
中的参数会传入到错误处理中间件的err
参数。
next
中传入route
和router
的参数时会略过其他路由回调函数
注意: 由于JS
代码是从上向下执行的,所以错误处理中间件和上面提到的用来捕获未定义路由的应用级中间件通常是放到代码的最下边(app.listen
之前)
express.static
是 Express
唯一内置的中间件。它基于 serve-static
,负责在 Express
应用中托管静态资源。
每个应用可有多个静态目录。
app.use(express.static('public'))
将静态资源文件所在的目录作为参数传递给 express.static
中间件就可以提供静态资源文件的访问了。
例如,假设在 public
目录放置了一个index.html
,我们就可以直接通过http://localhost:3000/index.html
来访问它:
所有文件的路径都是相对于存放目录的,因此,存放静态文件的目录名不会出现在 URL 中
如果你的静态资源存放在多个目录下面,你可以多次调用 express.static
中间件:
app.use(express.static('public'))
app.use(express.static('files'))
访问静态资源文件时,express.static
中间件会根据目录添加的顺序查找所需的文件。
如果你希望所有通过 express.static
访问的文件都存放在一个“虚拟(virtual
)”目录(即目录根本不存在)下面,可以通过为静态资源目录指定一个挂载路径的方式来实现,如下所示:
app.use('/static', express.static('public'))
现在,你就可以通过带有 “/static
” 前缀的地址来访问 public
目录下面的文件了:
Express
还具有很多的第三方中间件供我们下载使用,我们只需通过npm
安装所需功能的中间件,并在应用中加载即可(可以在应用级加载,也可以在路由级加载)。
下面的例子安装并加载了一个解析 cookie
的中间件: cookie-parser
安装:
npm install cookie-parser
加载使用:
var express = require('express')
var app = express()
var cookieParser = require('cookie-parser')
// 加载用于解析 cookie 的中间件
app.use(cookieParser())
博主的Node.js从入门到精通专栏正在持续更新中,关注博主订阅专栏学习Node不迷路!
如果本篇文章对你有所帮助,还请客官一件四连!❤️