Express中间件和路由及响应方法

1.中间件分类

应用程序级别中间件

通过 app.use()app.METHOD()(如 app.get)绑定的中间件,作用于整个应用程序。例如

记录请求日志、解析请求体等全局功能。例如:

javascript 复制代码
app.use((req, res, next) => {
  console.log('Request URL:', req.url);
  next();
});
 
路由级别中间件

绑定到 router.use()router.METHOD() 的中间件,仅对特定路由生效。常用于分组路由的

共享逻辑(如权限校验)。例如:

javascript 复制代码
const router = express.Router();
router.use((req, res, next) => {
  if (req.user.isAdmin) next();
  else res.status(403).send('Forbidden');
});
 
错误处理中间件

接收四个参数 (err, req, res, next),用于捕获并处理同步/异步错误。需定义在中间件链

末尾。例如:

javascript 复制代码
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send('Server Error');
});
 
内置中间件

Express 提供的开箱即用功能,如 express.json() 解析 JSON 请求体:

javascript 复制代码
app.use(express.json());
第三方中间件

通过 npm 安装的中间件,例如 cors 处理跨域、helmet 增强安全性:

javascript 复制代码
app.use(require('cors')());

2.中间件的使用

app.js文件中:

javascript 复制代码
const express = require("express");

const app = express();
const routerIndex=require("./router/index")
const videoRouter=require("./router/vedio")
const PORT = process.env.PORT || 3000;


// 设置日志中间件 中间件代码的位置很有讲究 必须是所有路由的前面才行
app.use((req, res, next) => {
  console.log(`${req.method} ${req.url},${Date.now()}`);
  // 继续处理下一个中间件或路由处理函数
  next();
},function(req, res, next) { 
  console.log('输出了日志,然后就可以执行这里面的代码,可以写多个这样的函数,然后使用next()执行下一个函数');
  next();
});
// 当有四个参数时,会默认这是个错误处理中间件
app.use((err,req,res,next)=>{
  console.log(err,'错误信息');
  res.status(500).send("服务器错误")
})
// 挂载路由  所有的路由前面都要加 /api,相当于vue的反向代理
app.use('/api',routerIndex);
app.use('/vedio',videoRouter)
// 挂载统一处理服务端错误中间件
// app.use(errorHandler());


// all 方法,可以处理 /xx 路径传过来的所有请求方法都可以触发,不管时get、post、put请求都会触发它
app.all('/xx',(req,res)=>{
  res.send('xx')
})

app.listen(PORT, () => {
  console.log(`Server is running at http://localhost:${PORT}`);
});

在app.js文件同级的router文件夹下的index.js:

javascript 复制代码
const express = require('express')

const router = express.Router()

router.get('/',(req,res)=>{
    console.log(req.method);
    res.send('/index')
})
router.get('/users',(req,res)=>{
    console.log(req.method);
    res.send('/users')
})

module.exports = router

在app.js文件同级的router文件夹下的vedio.js:

javascript 复制代码
const express =require('express')
const router=express.Router()
// 这里的路由不是前端的跳转页面路由,而是后端的接口路由路径
router.get('/list',(req,res)=>{
    console.log('list');
    res.send('list')
})
module.exports=router

3.路由

javascript 复制代码
// 可以匹配正则,/us+er表示匹配多个s叠加的路径,比如/usser、/ussser
app.get('/us+er',(req,res)=>{
  res.send(`${req.method} ${req.url}`)
})

获取路由参数:

javascript 复制代码
router.get('/list/:id',(req,res)=>{
    // 获取路由参数
    console.log(req.params.id);
    res.send('list')
})

还可以链式调用:

javascript 复制代码
router.get('/list/:id/are/:age',(req,res)=>{
    // 获取路由参数
    console.log(req.params.id);  // {id:2,age:3}
    res.send('list')
})
.post('/vedio',(req,res)=>{
    res.send('list')
})

使用res.render渲染:

javascript 复制代码
// app.js文件
const express = require("express");
const app = express();
const path = require('path');
// 设置模板引擎(以 EJS 为例)
app.set('view engine', 'ejs');
// 设置视图文件目录
app.set('views', path.join(__dirname, 'views'));
const routerIndex=require("./router/index")
// 所有的路由前面都要加 /api,相当于vue的反向代理
app.use('/api',routerIndex);

// router/index.js文件
const express = require('express')
const router = express.Router()
router.get('/',(req,res)=>{
    console.log(req.method);
      // res.render 是服务器端渲染,页面跳转到views/test/index.html页面中 
      res.render('test/index', { name: 'Express 路由1' });
    // res.send('/index')
})
module.exports = router

// views/test/index.ejs文件
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
    />
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title><%= name %></title>
  </head>
  <body>
    <h1>Hello, <%= name %></h1>
  </body>
  <script>
    function corsGetData() {
      alert("dsafdsafdsafsda");
    }
  </script>
</html>


// 安装ejs
npm install ejs

效果:(请求 http://127.0.0.1:3000/api/ 直接渲染页面)

其他的响应方法:

javascript 复制代码
// 这里的路由不是前端的跳转页面路由,而是后端的接口路由路径
router.get('/list/:id',(req,res)=>{
    // 获取路由参数
    console.log(req.params.id);
    // 下载文件  提示客户端下载文件
    res.download('./files/report.pdf')
    // 结束响应过程  不发送任何数据,直接结束响应
    // 通常用于简单响应或与 res.write() 配合使用
    res.end()
    // 发送 JSON 格式的响应 自动设置 Content-Type 为 application/json
    res.json({ message: 'Hello World' })
    // 重定向到指定的 URL  默认发送 302 状态码
    res.redirect('/login')
    // 渲染模板引擎视图
    res.render('index.ejs', { title: '首页' })
    // res.render 是服务器端渲染,页面跳转到views/test/index.html页面中 
    res.render('test/index', { name: 'Express 路由1' });
    // 发送文件作为响应
    res.sendFile('/views/index.html')
    // 设置响应状态码并发送其字符串表示作为响应体
    res.sendStatus(404) // 会发送 404 状态码和 "Not Found" 字符串


    res.send('list')
})

4. 设置跨域和记录日志

javascript 复制代码
// 跨域
npm i cors
// 请求日志中间件
npm i morgan

在app.js文件中:

javascript 复制代码
const cors =require('cors')
const morgan =require('morgan')
app.use(cors())
app.use(morgan('dev'))// 只记录开发时的日志
相关推荐
张人玉16 小时前
基于 Vue 3 + ECharts + Express + SQLite 构—— LDA 模型的新闻舆论主题识别与情感分析系统
vue.js·echarts·express
Maiko Star16 小时前
FastAPI 进阶三部曲:中间件、依赖注入与 ORM 实战
python·中间件·fastapi
憧憬成为java架构高手的小白2 天前
黑马八股--中间件学习之MQ(RabbitMQ)
学习·中间件
张人玉3 天前
基于 Vue 3 + ECharts + Express + SQLite 的可视化大屏与业务管理系统——YOLOv8 高精度车辆行人检测与计数系统
数据库·vue.js·yolo·sqlite·echarts·express
weixin_727535624 天前
MinIO大文件上传深度拆解:从原理到生产落地的完整指南
java·中间件
张人玉4 天前
基于 Vue 3 + ECharts + Express + SQLite 构建的鞋类零售数据分析与毛利预测平台——基于深度学习的鞋类销售数据分析系统
vue.js·sqlite·echarts·express
jieyucx4 天前
Nuxt4阶段六:工程化与进阶 —— 模块、中间件、插件、TS 与测试
中间件·vue·web·nuxt·全栈·ssr
索西引擎6 天前
【React】Redux 中间件机制:副作用处理与数据流增强的形式化分析
前端·react.js·中间件
糖果店的幽灵6 天前
【DeepAgents 从入门到精通】Context Management 上下文管理
java·人工智能·后端·spring·中间件·langgraph·deepagents
熊文豪7 天前
【金仓数据库征文】不装中间件的 MySQL→金仓在线迁移,mysql_fdw 全流程,和一个差点漏掉的 emoji
数据库·mysql·中间件·电科金仓