Express中间件应用于所有方法,而不是应用于控制器中定义的那些方法

时间:2018-01-17 14:38:55

标签: javascript express cors

我定义了只有一个函数的控制器,并且此函数被设置为对“GET / user / request”的回调:

class UserController {
  async getAllUserData(req, res) { /* get data, return res */ }
  async changepassword(req, res) { /* change password, return res */ }
}

const ctrl = new UserController();

api.get('/user', middlewareA, ctrl.getAllUserData);
api.post('/changepassword', ctrl.changepassword);

export default api;

这很好用,中间件仅适用于GET /user路由。但是,我想为单个控制器文件中定义的所有函数指定中间件,并在我的index.js文件的级别上应用此中间件,如下所示:

/* initialization... */

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Token');
  res.header('Access-Control-Allow-Methods', 'POST, GET, PUT, DELETE, OPTIONS');
  next();
});

app.use(middleware, UserController);

app.listen(3000, () => {
  console.log('Example app listening on port 3000!');
});

然而,在第二个片段中,当我在UserController之前放置中间件时,这个中间件应用于所有方法 - 尤其是对浏览器发送的OPTIONS请求 - 甚至认为UserController只有2个方法其中包含GETPOST方法。

为什么第二个代码段中的中间件应用于所有方法?我是否必须将它单独放在每个控制器的每个功能中?

1 个答案:

答案 0 :(得分:3)

在express中,按顺序调用与app.use()链接的所有内容。这是你的第二个片段中会发生的事情:

  1. 请求开始
  2. 运行标头中间件
  3. 运行您的中间件' (UserController之前包含的那个)
  4. 运行UserController
  5. 运行路线中间件
  6. 返回回复
  7. 需要注意的主要事项是中间件和路由中间件是相同的,它们将按照app.use()的顺序发生。

    您可以像在第一个代码段中那样分配中间件,也可以检查中间件中的URL。另一种选择是对您的网址进行分组。

    app.use('/example', middleware);
    app.use('/example', UserController);
    
    // ........
    api.get('/example/user', middlewareA, ctrl.getAllUserData);
    api.post('/example/changepassword', ctrl.changepassword);
    

    express documentation中有很多例子。