一、什么是中间件
官网对它的阐述是这样的:
“Express是一个自身功能极简,完全是路由和中间件构成一个web开发框架:从本质上来说,一个Express应用就是在调用各种中间件。”
中间件的作用就是专门用来接收请求和处理请求的。对于同一个请求express可以设置多个中间件,这些中间件会按照顺序依次对请求进行处理。下面这张图就是描述中间件处理请求的过程,当客户端向服务器端发送请求的时候中间件就可以直接处理请求,当中间件处理完请求之后可以直接响应给客户端返回结果也可以把这个请求交给下一个中间件继续进行处理,然后由下一个中间件对客户端进行响应。如果把请求看作是一条河流,那么中间件就相当于这条河流当中的一道道阀门,你可以在阀门处进行拦截或者排污等等处理。
中间件机制有什么好处?
我们可以将一个复杂的请求处理逻辑进行分开处理,也可以在请求到达路由之前做一些验证。比如查看用户是否登录,如果登录再向下继续执行。
中间件主要由两部分构成,中间件方法
以及请求处理函数
。
- 中间件方法由Express提供,负责拦截请求
- 请求处理函数由开发人员提供,负责处理请求
app.get('请求路径', '处理函数') // 接收并处理get请求
app.post('请求路径', '处理函数') // 接收并处理post请求
中间件划重点
- 可以针对同一个请求设置多个中间件,对同一个请求进行多次处理。
- 默认情况下,请求从上到下依次匹配中间件,一旦匹配成功,终止匹配。
- 可以调用
next()
方法将请求的控制权交给下一个中间件,直到遇到结束请求的中间件。
二、中间件应用
1、路由保护,客户端在访问需要登录的页面时,可以先使用中间件判断用户登录状态,用户如果未登录,则拦截请求,直接响应,禁止用户进入需要登录的页面。
代码示例:
// 引入express框架
const express = require('express');
// 创建网站服务器
const app = express();
app.use('/admin', (req, res, next) => {
// 用户没有登录
let isLogin = true;
// 如果用户登录
if (isLogin) {
// 让请求继续向下执行
next()
}else {
// 如果用户没有登录 直接对客户端做出响应
res.send('您还没有登录 不能访问/admin这个页面')
}
})
app.get('/admin', (req, res) => {
res.send('您已经登录 可以访问当前页面')
})
// 监听端口
app.listen(3000);
console.log('网站服务器启动成功');
当isLogin = true
时
当isLogin = false
时
2、网站维护公告,在所有路由的最上面定义接收所有请求的中间件,直接为客户端做出响应,网站正在维护中。
代码示例:
// 引入express框架
const express = require('express');
// 创建网站服务器
const app = express();
// 网站公告
app.use((req, res, next) => {
res.send('当前网站正在维护...')
})
// 监听端口
app.listen(3000);
console.log('网站服务器启动成功');
3、自定义404页面
代码示例:
// 引入express框架
const express = require('express');
// 创建网站服务器
const app = express();
app.use((req, res, next) => {
// 为客户端响应404状态码以及提示信息
res.status(404).send('当前访问的页面是不存在的,哈哈哈')
})
// 监听端口
app.listen(3000);
console.log('网站服务器启动成功');
三、app.use中间件用法
app.use 匹配所有的请求方式,可以直接传入请求处理函数,代表接收所有的请求。
app.use((req, res, next) => {
console.log(req.url);
next();
});
app.use 第一个参数也可以传入请求地址,代表不论什么请求方式,只要是这个请求地址就接收这个请求。
app.use('/admin', (req, res, next) => {
console.log(req.url);
next();
});
四、错误处理中间件
在程序执行的过程中,不可避免的会出现一些无法预料的错误,比如文件读取失败,数据库连接失败。
错误处理中间件是一个集中处理错误的地方。
app.use((err, req, res, next) => {
res.status(500).send('服务器发生未知错误');
})
当程序出现错误时,调用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('./01.js', 'utf8', (err, result) => {
if (err != null) {
next(err)
}else {
res.send(result)
}
})
})
// 错误处理中间
app.use((err, req, res, next) => {
res.status(500).send(err.message);
})
// 监听端口
app.listen(3000);
console.log('网站服务器启动成功');
五、捕获错误
运行时错误是无法避免的,一旦出现运行时错误,将造成程序崩溃,无法继续执行,因此必须对运行时错误加以处理。处理运行时错误的过程称为错误捕获(Error Trapping)。
运行时错误是VB编程中的一种错误,应用程序正在运行期间,当一个语句试图执行一个不能执行的操作时就会发生运行时错误。比较常见的有一个除法运算的除数为零,尽管在语法看来程序语句没有错误,但在实际上这条语句不能执行。
程序运行中的错误,一旦出现将造成程序崩溃,无法继续执行。因此我们必须对可能发生的运行时错误加以处理,也就是在系统发出警告之前,截获该错误,在错误处理程序中提示用户采取行动,是解决问题还是取消操作。如果用户解决了问题,程序就能够继续执行,如果用户选择取消操作,则可以跳出这段程序,继续执行后面的程序。这就是处理运行时错误的方法,这个过程称为错误捕获。
在node.js中,异步API的错误信息都是通过回调函数获取的,支持Promise
对象的异步API发生错误可以通过catch
方法捕获。
异步函数执行如果发生错误要如何捕获错误呢?
try catch
可以捕获异步函数以及其他同步代码在执行过程中发生的错误,但是不能
捕获其他类型的API发生的错误。如回调函数的错误、promise对象的。
代码示例:
// 引入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 (ex) {
next(ex);
}
})
// 错误处理中间
app.use((err, req, res, next) => {
res.status(500).send(err.message);
})
// 监听端口
app.listen(3000);
console.log('网站服务器启动成功');
您可能感兴趣的文章: