ctx.status = 501;
// 设置响应头中的allow字段,返回允许的http方法
ctx.set('Allow', allowedArr.join(', '));
}
} else if (allowedArr.length) {
if (ctx.method === 'OPTIONS') {
// 如果是OPTIONS请求,则认为是请求成功,响应200,并根据OPTIONS请求约定返回允许的http方法
ctx.status = 200;
ctx.body = '';
ctx.set('Allow', allowedArr.join(', '));
} else if (!allowed[ctx.method]) {
// 如果请求方法在router实例的methods中存在,但是在匹配的路由中该http方法不存在
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 {
// 响应405 http请求方法错误
ctx.status = 405;
ctx.set('Allow', allowedArr.join(', '));
}
}
}
}
});
};
};
Router.prototype.use
/**
* Use given middleware.
*
* Middleware run in the order they are defined by `.use()`. They are invoked
* sequentially, requests start at the first middleware and work their way
* "down" the middleware stack.
*
* @example
*
* ```javascript
* // session middleware will run before authorize
* router
* .use(session())
* .use(authorize());
*
* // use middleware only with given path
* router.use('/users', userAuth());
*
* // or with an array of paths
* router.use(['/users', '/admin'], userAuth());
*
* app.use(router.routes());
* ```
*
* @param {String=} path
* @param {Function} middleware
* @param {Function=} ...
* @returns {Router}
*/
Router.prototype.use = function () {
var router = this;
var middleware = Array.prototype.slice.call(arguments);
var path; // support array of paths
// 如果第一个参数是一个数组,且数组中元素为字符串
if (Array.isArray(middleware[0]) && typeof middleware[0][0] === 'string') {
// 递归调用use方法
middleware[0].forEach(function (p) {
router.use.apply(router, [p].concat(middleware.slice(1)));
});
return this;
}
var hasPath = typeof middleware[0] === 'string';
if (hasPath) {
path = middleware.shift();
}
middleware.forEach(function (m) {
// 如果这个中间件是由router.routes()方法返回的dispatch中间件,即这是一个嵌套的路由
if (m.router) {
// 遍历router.stack属性中所有的layer
m.router.stack.forEach(function (nestedLayer) {









