中间件
什么是中间件
中间件(Middleware)本质是一个回调函数,中间件函数可以像路由回调一样访问请求对象(request),响应对象(response)。
中间件的作用
使用函数封装公共操作,简化代码。
中间件的类型
- 全局中间件
- 路由中间件
中间件
案例
- 记录日志。
const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();
app.get('/home', (req, res) => {
let { url, ip } = req;
fs.appendFileSync(path.resolve(__dirname, './access.log'), `${url} ${ip}\r\n`);
// 记录日志
res.send('前台首页');
});
app.get('/admin', (req, res) => {
res.send('后台首页')
})
app.all('*', (req, res) => {
res.send('<h1>404 Not Found</h1>')
})
app.listen(3000, () => {
console.log('服务已经启动...');
})
当所有路由规则都需要记录日志时
const express = require('express');
const fs = require('fs');
const path = require('path');
const app = express();
// 1. 申明中间件函数 req:请求对象,res:响应对象,next:指向下一个中间件或路由处理器的函数。
function recordMiddleware(req, res, next) {
// 2. 提取公共代码
let { url, ip } = req;
// 记入日志
fs.appendFileSync(path.resolve(__dirname, './access.log'), `${url} ${ip}\r\n`);
// 4. 调用next,当中间件完成它的任务时,必须调用此函数以将控制权传递给后续的中间件或路由处理器。如果不调用 next(),那么请求将被阻塞,后续的中间件或路由处理器将不会被执行。
next();
};
// 3. 使用(注册)中间件函数, 这样所有传入的请求都会先经过这个中间件
app.use(recordMiddleware);
app.get('/home', (req, res) => {
res.send('前台首页');
});
app.get('/admin', (req, res) => {
res.send('后台首页')
})
app.all('*', (req, res) => {
res.send('<h1>404 Not Found</h1>')
})
app.listen(3000, () => {
console.log('服务已经启动...');
})
- 路由中间件,实现一个简单的访问控制功能(通常用于登录验证),只有当请求携带正确的 code 查询参数时,才能访问
/admin
路由。如果 code 不正确,则返回 “错误访问” 的消息。其他路由不受此访问控制的影响。
const express = require('express');
const app = express();
function enterCode(req, res, next) {
if (req.query.code === '111') {
// 符合条件继续执行后续逻辑
next();
} else {
res.send('错误访问');
}
}
app.get('/home', (req, res) => {
res.send('前台首页');
});
// 需要授权的路由规则
app.get('/admin', enterCode, (req, res) => {
res.send('后台首页')
})
app.all('*', (req, res) => {
res.send('<h1>404 Not Found</h1>')
})
app.listen(3000, () => {
console.log('服务已经启动...');
})
这种简单的认证方式仅适用于示例或测试环境。在生产环境中,应该使用更安全的身份验证机制,如 JWT(JSON Web Tokens)、OAuth 等。
express静态资源中间件
在Node.js中,静态资源通常指的是那些不需要服务器端脚本处理的文件,例如HTML页面、CSS样式表、JavaScript文件、图片、字体文件等。这些文件通常是直接提供给浏览器或者其他客户端的,不需要经过任何处理或修改。
当你构建一个使用Node.js的应用程序时,可能会有一个特定的目录来存放这些静态资源,这个目录一般称为“静态资源目录”或者“网站根目录”。
简单而言,就是浏览器发送请求到服务端=>服务端到某个文件夹中找到对应文件(静态资源)=>响应结果
const express = require('express');
const path = require('path');
const app = express();
// 指定public目录作为静态资源目录
app.use(express.static(path.join(__dirname, 'public')));
// 其他路由和中间件...
app.listen(3000, () => {
console.log('Server is running on http://localhost:3000');
});
public
参数就是静态资源文件夹的路径。
在根目录创建public
,新建index.html
写一些内容,访问http://127.0.0.1:3000/index.html
或者新建css
文件夹,创建app.css
文件
* {
margin: 0;
padding: 0;
}
同理,静态资源图片也可以这样实现。
静态资源中间件注意事项
- index.html 文件为默认打开的资源
直接访问根路径 http://127.0.0.1:3000/,而没有指定具体的文件名,那么服务器会尝试查找这个目录下的index.html
文件。这是因为在很多Web服务器配置中,index.html
是默认文档,它会在没有指定其他文件的情况下被自动提供给客户端。就会访问index.html
中的内容。
- 如果静态资源与路由规则同时匹配,谁先匹配上就响应谁,Express处理请求的方式是从第一个注册的路由开始检查(可以理解
JS
自上而下执行),直到找到匹配为止。因此,如果你有静态资源中间件(如express.static或者pxpress.public)并且还有其他的路由处理器,那么它们的顺序决定了哪个会被首先匹配到。
- 静态资源优先:如果你想让静态资源被优先处理**,**你需要在你的路由定义之前添加静态资源中间件。这样,任何对静态文件的请求都会被静态资源中间件处理,而不是被路由处理器处理。
// 指定public目录作为静态资源目录
app.use(express.static(path.join(__dirname, 'public')));
app.get('/',(req, res)=> {
res.send('路由处理器');
})
- 如果你想让某些特定的URL模式跳过静态资源处理,你应该将这些路由放在静态资源中间件之前。这样,这些特定的URL模式会被路由处理器捕获,而不是由静态资源中间件处理。
// 指定public目录作为静态资源目录
app.get('/',(req, res)=> {
res.send('路由处理器');
})
app.use(express.static(path.join(__dirname, 'public')));
- 路由响应动态资源,静态资源中间件响应静态资源。