koa-router allowedMethods

作者: 公里柒 | 来源:发表于2017-08-27 13:01 被阅读2269次

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

    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

        本文链接:https://www.haomeiwen.com/subject/mxbbdxtx.html