allowedMethods()中间件主要用于处理options请求,响应405和501状态。上述代码中的ctx.matched中保存的正是前面matched对象中的path(在routes方法中设置,后面会提到。),在matched对象中的path数组不为空的前提条件下:
服务器不支持当前请求方法,返回501状态码;
当前请求方法为OPTIONS,返回200状态码;
path中的layer不支持该方法,返回405状态;
对于上述三种情况,服务器都会设置Allow响应头,返回该路由路径上支持的请求方法。
2、routes()
Router.prototype.routes = Router.prototype.middleware = function () { var router = this; // 返回中间件处理函数 var dispatch = function dispatch(ctx, next) { var path = router.opts.routerPath || ctx.routerPath || ctx.path; var matched = router.match(path, ctx.method); var layerChain, layer, i; // 【1】为后续的allowedMethods中间件准备 if (ctx.matched) { ctx.matched.push.apply(ctx.matched, matched.path); } else { ctx.matched = matched.path; } ctx.router = router; // 未匹配路由 直接跳过 if (!matched.route) return next(); var matchedLayers = matched.pathAndMethod var mostSpecificLayer = matchedLayers[matchedLayers.length - 1] ctx._matchedRoute = mostSpecificLayer.path; if (mostSpecificLayer.name) { ctx._matchedRouteName = mostSpecificLayer.name; } layerChain = matchedLayers.reduce(function(memo, layer) { // 【3】路由的前置处理中间件 主要负责将params、路由别名以及捕获数组属性挂载在ctx上下文对象中。 memo.push(function(ctx, next) { ctx.captures = layer.captures(path, ctx.captures); ctx.params = layer.params(path, ctx.captures, ctx.params); ctx.routerName = layer.name; return next(); }); return memo.concat(layer.stack); }, []); // 【4】利用koa中间件组织的方式,形成一个‘小洋葱'模型 return compose(layerChain)(ctx, next); }; // 【2】router属性用来use方法中区别路由级别中间件 dispatch.router = this; return dispatch; };
routes()中间件主要实现了四大功能。
七、总结
koa-router虽然是koa的一个中间件,但是其内部也包含众多的中间件,这些中间件通过Layer对象根据路由路径的不同进行划分,使得它们不再像koa的中间件那样每次请求都执行,而是针对每次请求采用match方法匹配出相应的中间件,再利用koa-compose形成一个中间件执行链。
以上便是koa-router实现原理的全部内容,希望可以帮助你更好的理解koa-router。也希望大家多多支持脚本之家。
您可能感兴趣的文章: