我正在运行带有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();
});