Node.js 路由:构建灵活可扩展 Web 应用的关键

路由基本认知

设置基本路由

在了解了使用原生设置路由之后,接下来我们需要更进一步,使用express框架设置路由,以下是设置简单路由的基本步骤:

javascript 复制代码
  
  //1、引入express模块
  const express = require('express');
  //创建服务器实例
  const app = express();
  //创建监听端口
  const port = 3000;
  ​
  // 定义一个 GET 路由
  app.get('/', (req, res) => {
      res.send('Hello, World!');
  });
  ​
  // 定义一个 POST 路由
  app.post('/submit', (req, res) => {
      res.send('Form submitted!');
  });
  ​
  // 启动服务器
  app.listen(port, () => {
      console.log(`Server is running on               http://localhost:${port}`);
  });

当客户端发出"GET" 和 "POST"请求,如果请求根路径('/'),服务器返回"Hello World!",对于POST请求,请求路径为'/submit'时,服务器在3000端口返回对应路由信息。

路由参数

什么是路由参数

路由参数是URL路径中的动态部分,通常传递一些变量值,例如以下路由中:

javascript 复制代码
  
  app.get('/users/:userId', (req, res) => {
      const userId = req.params.userId;
      res.send(`User ID is ${userId}`);
  });
  • :userId 是一个路由参数,表示 URL 路径中的动态部分。
  • 当客户端访问 /users/123 时,req.params.userId 的值就是 "123"

如何获取路由参数 :req.params和req.query

req.params

Express 允许我们从前端发送的请求的URL中提取参数,并且通过req.params (是一个包含所有 从URL路径中提取的路由参数的对象)

获取前端发送的参数值,例如:

ini 复制代码
  
  app.get('/users/:userId/posts/:postId', (req, res) => {
      const userId = req.params.userId;
      const postId = req.params.postId;
      res.send(`User ID: ${userId}, Post ID: ${postId}`);
  });

如果客户端访问 /users/123/posts/456req.params 的值将是:

css 复制代码
  
  {
      userId:"123",
      postId:"456"
  }
req.query

req.query用于获取URL查询字符串中的参数,

如 (/users?name=John&age=30),下例:

javascript 复制代码
  
  app.get('/search', (req, res) => {
      const query = req.query.q;
      res.send(`Search query: ${query}`);
  });
  • 如果客户端访问 /search?q=expressreq.query.q 的值将是 "express"

路由中间件

什么是中间件

中间件是一个函数,它可以访问请求对象 (req)、响应对象 (res) 和 next 函数。其主要作用是:

  1. 执行某些逻辑(如验证、日志记录等)。

  2. 修改请求或响应对象。

  3. 决定是否继续执行后续的中间件或路由处理函数。

    -----------------看到这儿感觉是个提示器或校验器?我觉得前端发送请求后控制台中的请求反馈提示算是一个中间件?接着往下看看吧

中间件类型

在 Express 中,中间件可以分为以下几种类型:

  1. 应用级中间件 :绑定到 app 实例上,对所有请求生效。
  2. 路由级中间件:绑定到特定的路由上,只对该路由生效。
  3. 错误处理中间件:专门用于处理错误。
  4. 内置中间件 :Express 自带的中间件,如 express.json()
  5. 第三方中间件 :通过 npm 安装的中间件,如 body-parser

中间件的使用

接下来我们进入一个简单中间件的创建使用:

javascript 复制代码
  
  const app = express();
  const port = 3000;
  ​
  // 定义一个中间件函数
  const logRequest = (req, res, next) => {
      console.log(`Request URL: ${req.url}, Method: ${req.method}`);
      next(); // 调用 next() 继续执行后续的中间件或路由处理函数
  };
  ​
  // 将中间件应用到特定路由
  app.get('/users', logRequest, (req, res) => {
      res.send('User list');
  });
  ​
  // 启动服务器
  app.listen(port, () => {
      console.log(`Server is running on http://localhost:${port}`);
  });

上述logRequest中间件实现了记录请求信息,并且通过调用next()函数来执行中间件,得出的结果在终端中成功显示:

错误处理中间件

错误处理中间件专门用于捕获和处理错误 。它需要接收四个参数:err, req, res, next。例如:

javascript 复制代码
  
  app.use((err, req, res, next) => {
      console.error(err.stack);
      res.status(500).send('Something went wrong!');
  });

中间件代码的解析

  1. app.use()

    • app.use() 是 Express 中用于注册中间件的方法。
    • 它可以用于注册全局中间件或路由级中间件。
    • 在这里,它注册了一个错误处理中间件。
  2. 参数 (err, req, res, next)

    • 错误处理中间件有 4 个参数 ,分别是 errreqresnext
    • 与其他中间件(3 个参数:reqresnext)不同,错误处理中间件的第一个参数是 err,表示捕获到的错误对象。
  3. err

    • err 是捕获到的错误对象,通常由其他中间件或路由处理函数通过 next(err) 传递过来。
    • 它包含了错误的详细信息,例如错误消息、堆栈信息等。
  4. console.error(err.stack)

    • err.stack 是错误对象的堆栈信息,包含了错误发生的具体位置和调用链。
    • console.error() 将错误堆栈信息输出到控制台,方便开发者调试。
  5. res.status(500).send('Something went wrong!')

    • res.status(500) 设置 HTTP 响应状态码为 500(服务器内部错误)。
    • res.send('Something went wrong!') 向客户端发送一条简单的错误消息。
    • 这样,客户端会收到一个 500 错误响应,并显示 "Something went wrong!"。

在程序中任何地方调用next(err) 时,都会使用错误处理中间件

路由分组

什么是路由分组

路由分组是指将一组相关的路由(如 /users/users/:id 等)组织在一起,形成一个独立的路由模块

示例:

假设有一个用户相关的路由组,单独放在routes/users.js文件里:
javascript 复制代码
  
  // routes/users.js
  const express = require('express');
  const router = express.Router();
  ​
  // 定义用户相关的路由
  router.get('/', (req, res) => {
      res.send('User list');
  });
  ​
  router.get('/:id', (req, res) => {
      const userId = req.params.id;
      res.send(`User ID: ${userId}`);
  });
  ​
  router.post('/', (req, res) => {
      res.send('Create a new user');
  });
  ​
  module.exports = router;
在主应用中挂载路由分组
ini 复制代码
  
  // app.js
  const express = require('express');
  const app = express();
  const userRoutes = require('./routes/users');
  ​
  // 将用户路由分组挂载到 /users 路径
  app.use('/users', userRoutes);
  ​
  // 启动服务器
  const port = 3000;
  app.listen(port, () => {
      console.log(`Server is running on http://localhost:${port}`);
  });
3、运行结果
  • 访问 [http://localhost:3000/users](http://localhost:3000/users),返回 "User list"。
  • 访问 [http://localhost:3000/users/123](http://localhost:3000/users/123),返回 "User ID: 123"。
  • 发送 POST 请求到 [http://localhost:3000/users](http://localhost:3000/users),返回 "Create a new user"。

路由分组的优点

  1. 模块化:将相关路由组织在一起,便于维护和扩展。
  2. 代码复用:可以将路由分组模块化,并在多个应用中复用。
  3. 路径前缀:使用 app.use('/users', router) 可以为路由分组添加统一的前缀,避免重复书写路径。
  4. 中间件隔离:可以为不同的路由分组应用不同的中间件,实现更细粒度的控制。
相关推荐
几何心凉5 小时前
如何在Webpack中配置别名路径?
前端·webpack·node.js
天天扭码7 小时前
JS闭包不理解?一杯咖啡的时间带你轻松理解闭包!
javascript·面试·node.js
枫荷8 小时前
如何转换PPT里的音视频格式
前端·node.js
不想说话的麋鹿8 小时前
「项目实战」从0搭建NestJS后端服务(五):统一的响应拦截和异常错误过滤
node.js
还是鼠鼠10 小时前
Node.js 模块加载机制--详解
java·开发语言·前端·vscode·前端框架·npm·node.js
数据潜水员15 小时前
跨域,前端
node.js
前端菜鸟日常19 小时前
EJS缓存解决多页面相同闪动问题
前端框架·node.js
JustHappy1 天前
「工具链🛠️」Webpack、Vite、Rollup、Rspack我***到底怎么选?(为啥前端构建工具会分化成这样!)
前端·javascript·node.js
南风Y1 天前
命令行工具揭秘
前端·node.js·前端工程化
林梦泽1 天前
TurboFeLy:一个比Pjax更强的现代化界面无刷新加载库
javascript·node.js