首页 > 其他分享 >Express的使用笔记3 中间件

Express的使用笔记3 中间件

时间:2024-10-12 16:12:05浏览次数:7  
标签:req res app Express 中间件 笔记 next router





日志中间件

// 挂载会每个接口都执行这段代码
app.use((req,res,next)=>{
    console.log(req.method,req.url,Date.now())
    next() //下一个中间件
})

2.中间件的顺序很重要
如果有一个普通接口写在上面代码之前,那么就不会进入上面的函数中
但是如果在接口中第二个回调函数的参数中加入next,则可以进入

// 不会打印时间戳及相关信息
app.get("/todos", async (req, res) => {
  try {
    const db = await getDB();
    res.status(200).json(db.todos);
  } catch (err) {
    return res.status(500).json({ error: err.message });
  }
});
// 可以打印了~
app.get("/todos", async (req, res, next) => {
  try {
    const db = await getDB();
    res.status(200).json(db.todos);
    next()
  } catch (err) {
    return res.status(500).json({ error: err.message });
  }
});

我是讲武德的,这些课件截图源于b站up主小打小闹Studio
https://space.bilibili.com/13625996


在中间件函数中可以执行以下任何任务:
1).执行任何代码
2).修改request或response响应对象
3).结束请求响应周期
4).调用下一个中间件
如果当前的中间件功能没有结束请求-响应周期,则必须使用next()将控制权传递给下一个中间件功能。否则,该请求将被挂起。

2.Express中间件分类:
1)应用程序级别中间件 express实例.xxx
2)路由级别中间件 express.Router()
3)错误处理中间件 和其他中间件函数一样,但是四个参数
4)内置中间件
5)第三方中间件

1)通过Express实例挂载的中间件
a)不做任何限定的中间件

app.use((req, res, next) => {
  console.log(req.method, req.url, Date.now());
  next(); //下一个中间件
});

b)限定请求方法+请求路径的中间件
就是符合条件的APi被调用后才会进入这个中间件

//限定请求路径
app.use('/task',(req, res, next) => {
  console.log(req.method, req.url, Date.now());
  next(); //下一个中间件
});

app.get('/task',(req, res, next) => {
 res.status(200).send('是否会进入?')
})
//----页面进入/task中间件去打印方法和时间戳也会有‘是否进入’

//限定请求路径
app.use('/aaa',(req, res, next) => {
  console.log(req.method, req.url, Date.now());
  next(); //下一个中间件
});
//---这种就是不会进入打印了,因为匹配不上了

c)多个处理函数

app.use(
  "/",
  (req, res, next) => {
    console.log(req.method, req.url, Date.now());
    next();
  },
  (req, res, next) => {
    console.log('也会进来吗');
    // next();  //如果注释掉就不会进入下面的接口了
  }
);

app.get("/", (req, res, next) => {
  res.status(200).send("是否会进入?");
});

d)next('route') 下一步进入请求,而不是普通下一步

app.get(
  "/user/:id",
  function (req, res, next) {
    console.log(req.method, req.url, Date.now());
    console.log(typeof(req.params.id),'999')
    if (req.params.id === '2') {
      next("route"); //跳过也会进来吗函数的执行,直接进入是否会进入
    } else {
      next(); //继续往下执行
    }
  },
  function (req, res, next) {
    console.log("也会进来吗");
    next();
  }
);

app.get("/user/:id", (req, res, next) => {
  res.status(200).send("是否会进入?");
});

2)路由级别中间件
每个请求都需要app.xxx太过于繁琐 ,可以使用路由实例 相当于mini express 实例
后续就通过router.xxx()
a)根目录下创建一个router.js 文件,创建一个router实例

const express = require('express')
const router = express.Router()

b)配置路由

router.get('/',(req,res,next)=>{})

c) 导出路由实例

module.exports = router

d)将路由集成/挂载到Express实例应用中

const router = require('./router);
app.use(router)
//app.use('/abc',router) //在所有的路由前面都叫上限定访问的前缀

//可以将在app.js中写的所有路由配置放到router.js去

3)错误处理中间件
与其他中间件函数相同的方式定义错误处理中间件函数,除了使用四个参数而不是三个参数,一定是四个参数
一般在所有的中间件之后挂载错误处理函数中间

app.use((err,req,res,next)=>{
  console.log(err.stack)
  res.status(500).json({error:err.message})
})

在try catch中的catch里面使用next(err),传递错误的信息,跳过所有剩余的非错误处理路由和中间件函数,其实就是报错之后去触发错误处理函数,然后就结束任务
在router.js中将前面的所有路由中间件的catch里面都修改成next(err)

router.post("/todos", async (req, res,next) => {
  try {
    const db = await getDB();
    const reqBd = req.body;
    if (!reqBd.title) {
      return res.status(422).send({ error: "The field title is required" });
    }
    const lastTodoItem = db.todos[db.todos.length - 1];
    db.todos.push({
      id: lastTodoItem ? lastTodoItem.id + 1 : 1,
      title: reqBd.title,
    });
    await saveDB(db);
    res.status(200).send("添加成功!");
  } catch (err) {
    next(err);
  }
});

模拟一下报错的场景,正常可以响应500与对应的错误信息

通常我们会在最后的位置放置一个404的处理中间件函数,其实出现404的时候也有一个默认的html提示样式界面
404 与500类型的中间件没有先后的影响,会对应触发,但是其余会依此从上往下执行

app.use((req,res,next)=>{
  res.status(404).send('404 not found)
})

4)内置中间件
express.json() ---application/json
express.urlencoded() ---application/x-www-form-urlcoded
express.raw() ---application/octet-stream
express.text() ---text/plain
express.static() ---托管静态资源文件
5)第三方中间件
为了极简灵活的特性,epxress4之后将很多的中间件进行独立 ----middleware module
看文档使用即可
https://expressjs.com/zh-cn/resources/middleware.html

demo使用这些第三方中间件~~ 日志输出中间件
a)装包 npm install morgan
b)引入 var morgan = require('morgan')
c)挂载 app.use(morgan('tiny'))

标签:req,res,app,Express,中间件,笔记,next,router
From: https://www.cnblogs.com/jocelyn11/p/18458973

相关文章

  • 前缀和笔记
    前缀和笔记对于一个一维数组a[m]其前i项和记作s[i]如果想要对a[m]中任意连续段的值进行求和,例如a[l]~a[r]则可使用前缀和数组进行o(n)计算inta[m],s[m];s[0]=0;//定义s[0]的值,防止边界问题for(inti=0;i<m;i++){ cin>>a[i]; s[i]=s[i-1]+a[i];}这样的话,s......
  • 阅读笔记一:软件构建的本质与重要性(代码大全2)
    阅读笔记一:软件构建的本质与重要性《代码大全2》让我们深刻认识到软件构建是软件开发的核心环节。软件构建并非简单的代码编写,它是一个综合性的过程。软件构建就像建造一座大厦,从蓝图设计到一砖一瓦的搭建,都需要精心规划和细致执行。在这个过程中,我们要将抽象的业务需求转化为......
  • cmake使用笔记
    cmake_cxx_flags常用值在CMake中,CMAKE_CXX_FLAGS是一个用于指定C++编译器选项的变量。你可以将不同的编译选项添加到这个变量中,以影响编译过程的行为。以下是一些常用的CMAKE_CXX_FLAGS值及其说明:1.优化选项1.-O0:禁用优化(默认选项)。2.-O1:启用一级优化。3.-O2:启用二......
  • 关于C/CPP使用结构体中位域的一些笔记
    工作中软件通讯用到了结构体,在解析时,对应第一个变量在高位还是低位一直记不住。故计此博客作为笔记typedefstruct_stBin{ BYTEbOne:2; BYTEbTwo:2; BYTEbThree:2; BYTEbFour:2; _stBin() { bOne=0; bTwo=0; bThree=0; bFour=0; }}stB......
  • FFmpeg开发笔记(五十五)寒冬里的安卓程序员可进阶修炼的几种姿势
    ​喊了多年的互联网寒冬,今年的寒风格外凛冽,还在坚守安卓开发的朋友着实不容易。因为能转行的早就转了,能转岗的也早就转了,那么安卓程序员比较迷茫的就是,我该学什么安卓技术才好呢?还是直接扔了安卓再去搞别的技术吗?下面探讨下安卓程序员还能在哪些方面进阶修炼,主要有以下三个方向......
  • 神经网络与深度学习基础教程笔记(附案例讲解)
    神经网络与深度学习基础教程笔记(附案例讲解)引言神经网络和深度学习是人工智能领域中最重要的技术之一,它们在图像识别、自然语言处理、语音识别等领域取得了巨大的成功。本教程将从基础概念出发,逐步深入到高级主题,帮助你全面理解并掌握这些强大的工具。本文是神经网络与......
  • 界面控件DevExpress中文教程 - 如何拓展具有AI功能的文本编辑器(二)
    NLP是人工智能的一个分支,它允许计算机与人类语言进行交互,这包括以有意义/有用的方式理解、解释、生成和回应文本(和语音)的能力。基于NLP的功能允许更好的数据分析、个性化体验、高效的沟通,并导致更明智的决策和提高效率。例如:机器翻译文本摘要文本生成文本分类以及更多…......
  • ROS理论与实践学习笔记——4 ROS的常用组件之TF坐标变换
        tf:TransFormFrame,坐标变换    坐标系:ROS中是通过坐标系统开标定物体的,确切的将是通过右手坐标系来标定的。    作用:在ROS中用于实现不同坐标系之间的点或向量的转换。    说明:在ROS中坐标变换最初对应的是tf,不过在hydro版本开......
  • 《综合与Design Compiler》笔记
    《综合与DesignCompiler》笔记一直没系统的整理过DC这块的东西,这里借助一个挺好的文档《综合与DeisgnCompiler》以及我自己的经验和理解来归总一下。1.综合是什么综合是使用软件的方法来设计硬件,然后将门级电路实现与优化的工作留给综合工具的一种设计方法。它是根据一个系......
  • TensorFlow 学习笔记
    Tensorflow是谷歌开发的一款机器学习软件包。2019年,谷歌将Keras集成到Tensorflow中,并发布了Tensorflow2.0。Keras是FrançoisChollet独立开发的一个框架,为Tensorflow创建了一个简单的、以层为中心的接口。张量(Tensor)是数组的另一个名称。TensorFlow.orgimportte......