// next callback // 每次调用next都会从stack中取出一个中间件 var layer = stack[index++]
// all done // 如果不存在,说明中间件已经全部执行完毕, // 那么执行最后的一个收尾操作 // 你可以自定义收尾操作,没有定义就使用finalhandler这个模块来处理 if (!layer) { defer(done, err) return }
// route data // parseUrl是一个npm包,功能跟nodjs自带的url模块的parse方法一样, // 只不过加入了缓存处理,如果每次拿到相同的url就不在解析,直接返回缓存中的结果 // 这个path是你请求的path var path = parseUrl(req).pathname || '/' // 这个route是你在调用app.use(route, fn)中的route var route = layer.route
// skip this layer if the route doesn't match // 因为url是不区分大小写的,所以此处使用toLowerCase来统一处理 // 如果route为:/blog,path为:/blog/post, // 这个时候app.use('/blog', fn)中的fn是会执行的 // 此处用来处理path和route没有这种包含关系,那么跳过执行fn if (path.toLowerCase().substr(0, route.length) !== route.toLowerCase()) { return next(err) }
// skip if route match does not border "/", ".", or end // 如果path为:/blog-post, route为:/blog // 这种情况不满足包含关系,那么也跳过这个中间件的执行
// 如果path为:/blog.或者/blog/, route为:/blog // 这种情况也视为满足包含关系,也就是说会执行对应的中间件 var c = path.length > route.length && path[route.length] if (c && c !== '/' && c !== '.') { return next(err) }
// trim off the part of the url that matches the route if (route.length !== 0 && route !== '/') { // 如果route为:/blog,path为:/blog/post // 那么该url会被处理成 protohost + '/post'