koa-router allowedMethods

koa-router 是koa框架的一个路由处理级别的中间件

koa-router可以说是koa必须用上的一个库了, 其具体配置和用法我们直接查看源码或者官方文档,基于部分同学对router.allowedMethods()用法不理解,所以我们重点查看一下其中allowedMethods到底搞了什么猫腻,弄明白allowedMethods的应用场景

首先我们查阅koa-router的源码看到allowedMethods方法的申明

koa-router/lib/router.js (line-401)


Router.prototype.allowedMethods = function (options) {
  options = options || {};
  var implemented = this.methods;

  return function allowedMethods(ctx, next) {
    return next().then(function() {
      var allowed = {};

    //重点代码
    //当后续所有中间件执行完成之后,判断ctx的status,如果next中间件已经正确处理了response响应,则直接略过
      if (!ctx.status || ctx.status === 404) {
        ctx.matched.forEach(function (route) {
          route.methods.forEach(function (method) {
            allowed[method] = method;
          });
        });

        var allowedArr = Object.keys(allowed);

        if (!~implemented.indexOf(ctx.method)) {
          if (options.throw) {
            var notImplementedThrowable;
            if (typeof options.notImplemented === 'function') {
              notImplementedThrowable = options.notImplemented(); // set whatever the user returns from their function
            } else {
              notImplementedThrowable = new HttpError.NotImplemented();
            }
            throw notImplementedThrowable;
          } else {
            ctx.status = 501;
            ctx.set('Allow', allowedArr);
          }
        } else if (allowedArr.length) {
          if (ctx.method === 'OPTIONS') {
            ctx.status = 200;
            ctx.body = '';
            ctx.set('Allow', allowedArr);
          } else if (!allowed[ctx.method]) {
            if (options.throw) {
              var notAllowedThrowable;
              if (typeof options.methodNotAllowed === 'function') {
                notAllowedThrowable = options.methodNotAllowed(); // set whatever the user returns from their function
              } else {
                notAllowedThrowable = new HttpError.MethodNotAllowed();
              }
              throw notAllowedThrowable;
            } else {
              ctx.status = 405;
              ctx.set('Allow', allowedArr);
            }
          }
        }
      }
    });
  };
};

从源码中我们可以看到.allowedMethods处理的业务是当所有路由中间件执行完成之后,若ctx.status为空或者404的时候,丰富response对象的header头.

allowedMethods 应用场景

  1. 全局应用
  var Koa = require('koa');
  var Router = require('koa-router');
 
  var app = new Koa();
  var router = new Router();
 
  app.use(router.routes());
  app.use(router.allowedMethods());

这是官方文档的推荐用法,我们可以看到router.allowedMethods()用在了路由匹配router.routes()之后,所以在当所有路由中间件最后调用.此时根据ctx.status设置response响应头

  1. 局部应用

有的同学将他用在了路由级的中间件

  var Koa = require('koa');
  var Router = require('koa-router');
 
  var app = new Koa();
  var router = new Router();
  router.use('/test',router.allowedMethods())
  app.use(router.routes());

这时候只有当请求路径匹配到了/test才会执行allowedMethods,然后根据ctx.status设置response响应头

当然,如果我们不设置router.allowedMethods()在表现上除了ctx.status不会自动设置,以及response header中不会加上Allow之外,不会造成其他影响.

如果要设置,建议按照官方的写法,搞成全局的,路由级别的配置感觉很鸡肋

你可能感兴趣的:(koa-router allowedMethods)