Node.js 路由与中间件
一、路由(Routing)
1. 什么是路由?
路由是指根据客户端的请求路径和请求方法,将请求分配给对应的处理函数的机制。简单来说,就是"当用户访问某个 URL 时,服务器应该执行什么操作"。
2. 基本路由实现
在 Node.js 中,可通过原生 http
模块手动实现路由,也可使用 Express 框架简化操作。
(1)原生 http 模块实现
const http = require('http');const server = http.createServer((req, res) => {const { method, url } = req;// 设置响应头res.setHeader('Content-Type', 'text/plain; charset=utf-8');// 路由判断if (method === 'GET' && url === '/') {res.end('首页');} else if (method === 'GET' && url === '/about') {res.end('关于我们');} else if (method === 'POST' && url === '/login') {res.end('登录接口');} else {res.statusCode = 404;res.end('404 页面未找到');}
});server.listen(3000, () => {console.log('服务器运行在 http://localhost:3000');
});
(2)Express 框架实现
Express 内置了路由处理机制,更简洁高效:
const express = require('express');
const app = express();// GET 请求 - 首页
app.get('/', (req, res) => {res.send('首页');
});// GET 请求 - 关于页
app.get('/about', (req, res) => {res.send('关于我们');
});// POST 请求 - 登录接口
app.post('/login', (req, res) => {res.send('登录成功');
});// 404 处理
app.use((req, res) => {res.status(404).send('404 页面未找到');
});app.listen(3000, () => {console.log('Express 服务器运行在 http://localhost:3000');
});
3. 路由参数
用于匹配动态路径(动态参数)(如 /user/123
中的 123
为用户 ID):
// Express 中获取路由参数
app.get('/user/:id', (req, res) => {// req.params 包含路由参数const userId = req.params.id;res.send(`用户 ID:${userId}`);
});// 多参数示例
app.get('/user/:id/post/:postId', (req, res) => {res.send(`用户 ID:${req.params.id},文章 ID:${req.params.postId}`);
});
4. 路由模块化
当路由较多时,可拆分到单独文件中:
(1)创建路由模块(routes/user.js
)
const express = require('express');
const router = express.Router(); // 创建路由实例// 用户列表
router.get('/', (req, res) => {res.send('用户列表');
});// 用户详情
router.get('/:id', (req, res) => {res.send(`用户 ${req.params.id} 的详情`);
});module.exports = router; // 导出路由
(2)在主文件中使用
const express = require('express');
const app = express();
const userRouter = require('./routes/user');// 挂载路由,所有以 /user 开头的请求都会交给 userRouter 处理
app.use('/user', userRouter);app.listen(3000);
二、中间件(Middleware)
1. 什么是中间件?
中间件是在请求到达路由处理函数之前执行的函数,可用于处理请求、修改响应、实现功能复用(如日志记录、身份验证等)。
中间件的基本格式:
app.use((req, res, next) => {// 处理逻辑next(); // 调用 next() 进入下一个中间件或路由
});
req
:请求对象res
:响应对象next
:函数,调用后将控制权交给下一个中间件
2. 中间件的分类
(1)应用中间件
绑定到 app
实例的中间件,对所有请求生效:
// 日志中间件
app.use((req, res, next) => {console.log(`${new Date().toLocaleString()} - ${req.method} - ${req.url}`);next(); // 必须调用 next(),否则请求会被挂起
});// 验证中间件(仅对 /admin 路径生效)
app.use('/admin', (req, res, next) => {const isLogin = true; // 模拟登录状态if (isLogin) {next(); // 已登录,继续} else {res.send('请先登录');}
});
(2)路由中间件
与路由绑定的中间件,仅对特定路由生效:
// 路由级中间件(检查用户权限)
const checkPermission = (req, res, next) => {const hasPermission = true; // 模拟权限检查if (hasPermission) {next();} else {res.status(403).send('没有权限');}
};// 应用到路由
app.get('/admin/user', checkPermission, (req, res) => {res.send('用户管理页面');
});
(3)错误处理中间件
专门处理错误的中间件,有 4 个参数(err, req, res, next
):
app.use((err, req, res, next) => {console.error('错误:', err.stack);res.status(500).send('服务器内部错误');
});// 使用示例
app.get('/error', (req, res, next) => {try {throw new Error('自定义错误');} catch (err) {next(err); // 传递错误到错误中间件}
});
(4)第三方中间件
需通过 npm
安装的中间件(如 cors
处理跨域、morgan
日志记录):
npm install cors morgan
const cors = require('cors');
const morgan = require('morgan');// 允许跨域
app.use(cors());// 打印请求日志
app.use(morgan('combined'));
三. 总结
1. 路由:控制请求的分发,根据 method 和 url 匹配对应的处理函数,支持动态参数和模块化拆分。
2. 中间件:在请求处理流程中插入自定义逻辑,可实现日志、验证、错误处理等功能,按定义顺序执行,通过 next() 传递控制权。