> For the complete documentation index, see [llms.txt](https://zpliu.gitbook.io/booknote/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://zpliu.gitbook.io/booknote/node/zhong-jian-jian-gai-nian.md).

# express中中间件的概念

> 当请求进来时，默认从第一个中间件开始匹配，如果中间件中调用了next则继续往后面的中间件进行匹配

1. 不关心请求方法与请求路径

   ```javascript
   //第一个中间件
   app.use(function(req,rep,next){
      consloe.log(1) 
       next()
   })
   //第二个中间件
   app.use(function(req,rep,next){
      consloe.log(2) 
       next()
   })
   ```

   通过调用next方法进入下一个中间件
2. 关注请求路径的中间件

   ```javascript
   //所有以/ab、开头的请求都会进入中间件
   app.use("/ab",function(req,rep,next){
       console.log(req.url) //如果请求是"/ab/a" 这里的url是  "/a"
   })
   ```
3. 严格匹配请求方法与请求路径的中间件

   ```javascript
   app.get("/a",function(req,rep){

   })
   app.post("/a",function(req,rep){

   })
   ```

## 业务应用

```javascript
app.get("/",function(req,rep){
    req.user='aa';
    next()
})
app.get("/",function(req,rep){
    console.log(req.user)
})
```

同一个请求可以给req封装一些属性与方法，从而实现各种功能，这和body-parse 、session的实现思路是一样的

:warning:所以在配置app的时候，尽量让其他中间件在路由中间件之前配置好

针对不同的功能配置不同的中间件

<https://expressjs.com/en/resources/middleware.html>

## 配置404中间件

当请求不经过任何中间件，包括路由中间件的时候，就流向到了最后；因此可以在最后放置一个处理404的中间件;

其他中间件不能处理的请求，都交给404中间件来处理

```
//404 中间件
app.use(function(req,rep){
    rep.status(404).render("404.html")
})
```

## 配置错误处理中间件

> 记得在请求时加上next，方便使用**return next(err)**&#x8FDB;入错误处理中间件

```javascript
router.post("/register",function(req,rep,next){

    user.findOne('account',req.body.account,function(err,data){
        if(err){
            return next(
                errcode:1,
                message:"查询数据库出错"
            })
        }
}
 //错误处理中间件         
app.use(function(err,req,rep,next){
    rep.status(200).send(err)
})
```

1. 在配置路由的时候就传递一个next函数给路由，当请求出错是使用返回next(错误对象)
2. 错误处理中间件多了一个err参数，并且是按照顺序定义的
3. 进入错误中间件的时候给客户端发送对应的错误信息就可以了

   :warning:当进行异步请求时，错误中间件需要响应200的状态码，客户端能收到错误信息，但是在ajax中得不到对应的错误信息，只有undefined
4. 在设置好响应之后，不能出现next了，只有在出错的时候调用next函数，交给错误中间件进行处理

   `**Can't set headers after they are sent**`

   例如 <https://blog.csdn.net/zzwwjjdj1/article/details/52126352>
