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 = {};
//重點代碼
//當后續(xù)所有中間件執(zhí)行完成之后,判斷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
處理的業(yè)務是當所有路由中間件執(zhí)行完成之后,若ctx.status
為空或者404的時候,豐富response
對象的header
頭.
allowedMethods 應用場景
- 全局應用
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()
之后,所以在當所有路由中間件最后調用.此時根據(jù)ctx.status
設置response響應頭
- 局部應用
有的同學將他用在了路由級的中間件
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
才會執(zhí)行allowedMethods
,然后根據(jù)ctx.status
設置response響應頭
當然,如果我們不設置router.allowedMethods()
在表現(xiàn)上除了ctx.status
不會自動設置,以及response header
中不會加上Allow
之外,不會造成其他影響.
如果要設置,建議按照官方的寫法,搞成全局的,路由級別的配置感覺很雞肋