当前位置: 首页 > 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.dtcms.com/a/311035.html

相关文章:

  • [硬件电路-119]:模拟电路 - 信号处理电路 - 比较器,模拟电路中的“决策者”,模拟信号到数字电平逻辑信号的转化者...
  • 音视频学习(四十六):声音的三要素
  • 小迪23-28~31-js简单回顾
  • K8S的Pod之initC容器restartPolicy新特性
  • 强光干扰下识别精度提升28%!陌讯多模态融合算法在油罐车识别的落地实践
  • ubuntu源码编译安装cmake高版本、pybind11安装、crow使用
  • 第3章栈、队列、数组和矩阵
  • 译|Netflix 技术博客:一个利用视觉-语言模型和主动学习高效构建视频分类器的框架
  • 什么叫湖仓一体
  • 一个物理引擎仿真器(mujoco这种)的计算流程
  • ubuntu 系统风扇控制软件 CoolerControl
  • 烽火HG680-KD_海思MV320处理器-安卓9-原厂系统升级包-针对解决烧录不进系统的问题
  • 【Docker】RK3576-Debian上使用Docker安装Ubuntu22.04+ROS2
  • YOLO的Python实现以及 OpenCV
  • 分布式微服务--Nacos作为配置中心(补)关于bosststrap.yml与@RefreshScope
  • 分布式微服务--Nacos作为配置中心(二)
  • 多线程(一) ~ 进程与线程的区别
  • 深入 Go 底层原理(五):内存分配机制
  • 基于ELK Stack的实时日志分析与智能告警实践指南
  • 【vue】创建响应式数据ref和reactive的区别
  • React ahooks——副作用类hooks之useDebounceFn
  • Coze Studio 概览(六)--知识库管理
  • FreeRTOS源码分析一:task启动(RISCV架构)
  • 再见!三层框架开发
  • 【无标题】根据11维拓扑量子色动力学模型的严格计算宇宙轮回次数:
  • 谈谈WebAssembly、PWA、Web Workers的作用和场景
  • 论文阅读笔记:Dataset Condensation with Gradient Matching
  • 2023年影响重大的网络安全典型案例
  • OAuth 2.0 的安全升级版授权协议 OAuth 2.1 详解
  • 企业级单点登录(SSO)技术详解:从原理到安全实践