当前位置: 首页 > news >正文

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() 传递控制权。

http://www.xdnf.cn/news/1228285.html

相关文章:

  • StarRocks vs ClickHouse:2025 年 OLAP 引擎终极对比指南
  • 高效截图的4款工具深度解析
  • cmd怎么取消关机命令
  • Oracle 11g RAC集群部署手册(二)
  • C语言(长期更新)第7讲:VS实用调试技巧
  • 仿真电路:(十七下)DC-DC升压压电路原理简单仿真
  • 【DL学习笔记】计算图与自动求导
  • 鸿蒙智选携手IAM进驻长隆熊猫村,为国宝打造智慧健康呼吸新空间
  • [硬件电路-120]:模拟电路 - 信号处理电路 - 在信息系统众多不同的场景,“高速”的含义是不尽相同的。
  • C语言字符函数和字符串函数全解析:从使用到模拟实现
  • [硬件电路-115]:模拟电路 - 信号处理电路 - 功能放大器工作分类、工作原理、常见芯片
  • 深入 Go 底层原理(十一):Go 的反射(Reflection)机制
  • stm32是如何实现电源控制的?
  • Java 大视界 -- Java 大数据在智能安防视频监控系统中的视频摘要生成与智能检索优化进阶(377)
  • QT中使用OpenCV保姆级教程
  • 搜索与图论(最小生成树 二分图)
  • MyBatisPlus之核心注解与配置
  • Docker 部署与配置 MySQL 5.7
  • 位运算-371.两整数之和-力扣(LeetCode)
  • 解决 InputStream 只能读取一次问题
  • 【多模态】DPO学习笔记
  • [创业之路-528]:技术成熟度曲线如何指导创业与投资?
  • Python爬虫实战:研究mahotas库,构建图像获取及处理系统
  • 【DeepSeek-R1 】分词系统架构解析
  • 社群团购市场选择与开源技术赋能下的下沉市场开拓策略研究——以开源AI智能名片、链动2+1模式与S2B2C商城小程序为例
  • LLM Prompt与开源模型资源(3)如何写一个好的 Prompt
  • 【论文笔记】Multi-Behavior Graph Neural Networks for Recommender System
  • “神威·太湖之光”:科技创新引擎与国家算力基石的崛起之路
  • jenkins从入门到精通-P1—九五小庞
  • 机器学习 —— 决策树