我正在运行带有Express的标准NodeJs 8,目前,当出现对现有路径但不受支持的方法的请求时,Express返回404。

例如,支持“ POST / login”,但不支持“ GET / login”,但它返回404。

在这种情况下,如何使Express返回405?

这是路线文件:

const express = require('express');
const router = express.Router();
const loginController = require('../controllers/login');


router.route('/login').post(loginController.loginUser);

module.exports = router;


请指教。

最佳答案

您只需将.all()处理程序添加到路由链中,如下所示:

const methodNotAllowed = (req, res, next) => res.status(405).send();

router
.route(`/login`)
.post(loginController.loginUser)
.all(methodNotAllowed);


说明

之所以可行,是因为请求按照它们附加到路由的顺序(请求“瀑布”)传递到处理程序。 .post()处理程序将捕获您的POST请求,其余的将进入.all()处理程序。

另请参阅this question以获取更多详细信息。

验证所有POST路由

如果您想确保用户已登录所有POST请求,但为其他任何请求返回405响应,则可以使用正则表达式将所有路由与router.post('*')匹配,如下所示:

router
.post(`*`, loginController.loginUser)
.all(methodNotAllowed);


但是,这种方法的问题在于,不会向客户端返回404错误,而只会返回405错误。因此,我建议将methodNotAllowed处理程序附加到每个单独的路由,就像上面的第一个代码段一样。对于不存在的路由,此方法将返回404错误,而对于不存在的路由将返回405错误。

确定路线的可用方法

要确定允许路由的方法,请使用router.stack

app.use((req, res, next) => {

  const methods = router.stack

  // Filter for the route that matches the currently matched route
  .filter(layer => layer.route.path === req.path)[0]
  .route
  .methods;

  if (!methods[req.method]) methodNotAllowed(req, res, next);
  else next();

});

10-08 15:45