Sending 405 from express.js when there is a route match but no HTTP method match

后端 未结 6 1161
孤城傲影
孤城傲影 2020-12-30 02:33

I\'m looking for a clean way to have my express app return 405 Method Not Allowed if a client sends a request that matches a mapped url route but does not match the mapped H

6条回答
  •  太阳男子
    2020-12-30 02:40

    Method 1: Use .route() and .all()

    // Your route handlers
    const handlers = require(`./handlers.js`);
    
    // The 405 handler
    const methodNotAllowed = (req, res, next) => res.status(405).send();
    
    router
    .route(`/products`)
    .get(handlers.getProduct)
    .put(handlers.addProduct)
    .all(methodNotAllowed);

    This works because requests are passed to the handlers in the order they are attached to the route (the request "waterfall"). The .get() and .put() handlers will catch GET and PUT requests, and the rest will fall through to the .all() handler.

    Method 2: Middleware

    Create middleware which checks for allowed methods, and returns a 405 error if the method is not whitelisted. This approach is nice because it allows you to see and set the allowed methods for each route along with the route itself.

    Here's the methods.js middleware:

    const methods = (methods = ['GET']) => (req, res, next) => {
      if (methods.includes(req.method)) return next();
      res.error(405, `The ${req.method} method for the "${req.originalUrl}" route is not supported.`);
    };
    
    module.exports = methods;

    You would then use the methods middleware in your routes like this:

    const handlers = require(`./handlers.js`); // route handlers
    const methods = require(`./methods.js`);   // methods middleware
    
    // allows only GET or PUT requests
    router.all(`/products`, methods([`GET`, `PUT`]), handlers.products);
    
    // defaults to allowing GET requests only
    router.all(`/products`, methods(), handlers.products);

提交回复
热议问题