Node.js中间件的5个注意事项

目录

[1. 目录结构](#1. 目录结构)

[2. 代码实现](#2. 代码实现)

[注意事项 1:必须调用 next()](#注意事项 1:必须调用 next())

[注意事项 2:中间件的执行顺序很重要](#注意事项 2:中间件的执行顺序很重要)

[注意事项 3:局部中间件的使用](#注意事项 3:局部中间件的使用)

[注意事项 4:统一处理 404](#注意事项 4:统一处理 404)

[注意事项 5:使用错误处理中间件](#注意事项 5:使用错误处理中间件)

[3. 总结](#3. 总结)


在Node.js的Express框架中,中间件是处理请求和响应的关键组件,它可以用于日志记录、权限验证、错误处理等任务。使用中间件时,有一些重要的注意事项需要了解,以确保代码的稳定性和可维护性。下面,我们详细介绍5个注意事项,并提供示例代码帮助理解。


1. 目录结构

javascript 复制代码
/your-project
  ├── app.js                # 主文件,启动应用
  ├── middleware
  │   ├── logger.js         # 日志中间件
  │   ├── auth.js           # 身份验证中间件
  │   ├── requestTime.js    # 记录请求时间的中间件
  │   ├── notFound.js       # 404 处理中间件
  │   ├── errorHandler.js   # 全局错误处理中间件
  └── package.json          # 项目依赖管理文件

2. 代码实现

注意事项 1:必须调用 next()

中间件函数必须调用 next(),否则请求会卡住,无法继续执行下一个中间件或路由处理程序。

javascript 复制代码
// middleware/logger.js
const logger = (req, res, next) => {
  console.log(`Received ${req.method} request for ${req.url}`);
  next(); // 必须调用,否则请求不会继续
};

module.exports = logger;

app.js 中使用:

javascript 复制代码
// app.js
const express = require('express');
const app = express();
const logger = require('./middleware/logger');

app.use(logger);

app.get('/', (req, res) => {
  res.send('<h1>Home Page</h1>');
});

app.listen(3000, () => {
  console.log('Server running on http://localhost:3000');
});

运行结果: 访问 http://localhost:3000/ 时,控制台输出:

javascript 复制代码
Received GET request for /

注意事项 2:中间件的执行顺序很重要

Express 按照 app.use()app.get() 的顺序执行中间件,错误的顺序可能导致某些中间件失效。

javascript 复制代码
// middleware/requestTime.js
const requestTime = (req, res, next) => {
  req.requestTime = new Date();
  next();
};

module.exports = requestTime;

app.js 中:

javascript 复制代码
const requestTime = require('./middleware/requestTime');

app.use(requestTime);

app.get('/time', (req, res) => {
  res.send(`<h1>Request received at: ${req.requestTime}</h1>`);
});

访问 http://localhost:3000/time,页面会显示请求的时间。


注意事项 3:局部中间件的使用

中间件不一定要全局生效,可以局部应用于特定路由,以减少不必要的开销。

javascript 复制代码
// middleware/auth.js
const auth = (req, res, next) => {
  if (req.query.auth === 'true') {
    next(); // 通过认证
  } else {
    res.status(403).send('<h1>Access Denied</h1>');
  }
};

module.exports = auth;

app.js 中:

javascript 复制代码
const auth = require('./middleware/auth');

app.get('/dashboard', auth, (req, res) => {
  res.send('<h1>Welcome to the Dashboard</h1>');
});

访问 http://localhost:3000/dashboard?auth=true 显示:

bash 复制代码
Welcome to the Dashboard

访问 http://localhost:3000/dashboard 显示:

bash 复制代码
Access Denied

注意事项 4:统一处理 404

如果没有匹配的路由,应该使用一个中间件来返回 404,避免请求进入死循环。

javascript 复制代码
// middleware/notFound.js
const notFound = (req, res) => {
  res.status(404).send('<h1>404 - Not Found</h1>');
};

module.exports = notFound;

app.js 末尾添加:

javascript 复制代码
const notFound = require('./middleware/notFound');

app.use(notFound);

访问不存在的路由,如 http://localhost:3000/unknown,页面显示:

javascript 复制代码
404 - Not Found

注意事项 5:使用错误处理中间件

Express 提供了一个特殊的错误处理中间件,必须使用 err, req, res, next 作为参数。

javascript 复制代码
// middleware/errorHandler.js
const errorHandler = (err, req, res, next) => {
  console.error(`Error: ${err.message}`);
  res.status(500).send('<h1>Internal Server Error</h1>');
};

module.exports = errorHandler;

app.js 中:

javascript 复制代码
const errorHandler = require('./middleware/errorHandler');

app.get('/error', (req, res, next) => {
  const err = new Error('Something went wrong!');
  next(err); // 触发错误处理
});

app.use(errorHandler);

访问 http://localhost:3000/error,页面显示:

javascript 复制代码
Internal Server Error

终端输出:

javascript 复制代码
Error: Something went wrong!

3. 总结

  1. 必须调用 next(),否则请求会卡住。

  2. 中间件的执行顺序很重要,顺序错误可能导致某些功能失效。

  3. 局部中间件适用于特定路由,可以提高性能和安全性。

  4. 提供 404 处理,避免未匹配的请求进入死循环。

  5. 使用错误处理中间件,集中处理错误,提高可维护性。

希望本教程能帮助你更好地理解和使用Node.js的Express中间件!

相关推荐
这儿有一堆花1 小时前
重磅推出!Google Antigravity:一次 “以 Agent 为中心 (agent-first)” 的 IDE 革命
vscode·ai·ai编程·googlecloud
u***27611 小时前
TypeScript 与后端开发Node.js
javascript·typescript·node.js
星空的资源小屋1 小时前
跨平台下载神器ArrowDL,一网打尽所有资源
javascript·笔记·django
Dorcas_FE2 小时前
【tips】动态el-form-item中校验的注意点
前端·javascript·vue.js
八月ouc2 小时前
解密JavaScript模块化演进:从IIFE到ES Module,深入理解现代前端工程化基石
javascript·es6·模块化·cmd·commonjs·amd·iife
四岁爱上了她2 小时前
input输入框焦点的获取和隐藏div,一个自定义的下拉选择
前端·javascript·vue.js
烟袅3 小时前
5 分钟把 Coze 智能体嵌入网页:原生 JS + Vite 极简方案
前端·javascript·llm
神秘的猪头3 小时前
🧠 深入理解 JavaScript Promise 与 `Promise.all`:从原型链到异步编程实战
前端·javascript·面试
白兰地空瓶3 小时前
从「似懂非懂」到「了如指掌」:Promise 与原型链全维度拆解
前端·javascript
湖边看客4 小时前
antd x6 + vue3
开发语言·javascript·vue.js