表示对所谓 Web 框架只停留在写一下 app.get() 那种水平...
帖子写一半想起去看源码... 怎么偏偏找不到 app.get = 的具体代码
https://github.com/visionmedia/express/blob/master/lib/application.js
首先在前边看到获取变量的解释:
Get setting name value
app.get('title');
而后面又是我更熟悉的处理 GET 请求的用法..
app.get('/', function(req, res){
res.send('hello world');
});
这是为什么?
还有 app.params() app.use() app.engine() 我还好理解,
可前边的 app.set() 设置那么多变量那是做什么用的?
回复 (10)
/**
* Delegate `.VERB(...)` calls to `.route(VERB, ...)`.
*/
methods.forEach(function(method){
app[method] = function(path){
if ('get' == method && 1 == arguments.length) return this.set(path);
var args = [method].concat([].slice.call(arguments));
if (!this._usedRouter) this.use(this.router);
return this._router.route.apply(this._router, args);
}
});
若调用app.get()时只有一个参数,则认为是取设置值,否则认为是注册路由
@leizongmin 可恶的 arguments 变量.. 不敏感
那再请问下 app.use() 的路由是怎样作用上去的,
我看 app.use() 被用了很多次, 而且 404 之类也通过它实现的..
疑问主要是 app.get() 跟 app.use() 之前是什么关系啊?
终于有点懂了,, 所有被 app.use() 接收的 handle 会被放到一个 stack 里边
app.get() 执行的时候会把一条路由规则添加到 stack 里..
然后顺序检索 statck 直到结束, 那么执行这段代码给出 404
https://github.com/senchalabs/connect/blob/master/lib/proto.js#L122
// all done
if (!layer || res.headerSent) {
// delegate to parent
if (out) return out(err);
// unhandled error
if (err) {
// default to 500
if (res.statusCode < 400) res.statusCode = 500;
debug('default %s', res.statusCode);
// respect err.status
if (err.status) res.statusCode = err.status;
// production gets a basic error message
var msg = 'production' == env
? http.STATUS_CODES[res.statusCode]
: err.stack || err.toString();
// log to stderr in a non-test env
if ('test' != env) console.error(err.stack || err.toString());
if (res.headerSent) return req.socket.destroy();
res.setHeader('Content-Type', 'text/plain');
res.setHeader('Content-Length', Buffer.byteLength(msg));
if ('HEAD' == req.method) return res.end();
res.end(msg);
} else {
debug('default 404');
res.statusCode = 404;
res.setHeader('Content-Type', 'text/plain');
if ('HEAD' == req.method) return res.end();
res.end('Cannot ' + req.method + ' ' + utils.escape(req.originalUrl));
}
return;
}
不过这样的话,, 自己定义 404 页面是怎样做到的
https://github.com/visionmedia/express/blob/master/examples/error-pages/index.js#L45
@jiyinyiyong
app.get()这个功能是由一个叫router的中间件来处理的
默认创建的代码中有这一行,就是使用这个路由中间件:
app.use(app.router);
app.router的定义在这里:https://github.com/visionmedia/express/blob/master/lib/application.js#L70
// router
this._router = new Router(this);
this.routes = this._router.map;
this.__defineGetter__('router', function(){
this._usedRouter = true;
this._router.caseSensitive = this.enabled('case sensitive routing');
this._router.strict = this.enabled('strict routing');
return this._router.middleware;
});
router.middleware的代码:https://github.com/visionmedia/express/blob/master/lib/router/index.js#L32
this.middleware = function router(req, res, next){
self._dispatch(req, res, next);
};
这个_dispatch方法就是查找是否有注册匹配的路由,如果有则调用相应的函数,否则直接调用next()进入下一个中间件。
@leizongmin 好多代码看得乱了...
这么说所有的 GET POST 都是在同一个 middleware 里的?
那还有比如 404 这种特殊的路由怎样处理的呢?
@jiyinyiyong app.get('/ooxx', function () {});不是注册中间件,而是对中间件app.router进行配置(包括app.post(),app.all()等),虽然其工作机制跟middleware差不多,但不要混淆。
@leizongmin 我绕得有点晕了.. 我想理一下,
比方说我写了 app.use(..);app.get(...);, 两行代码,
那么 Express 内部的查询过程是怎么样的呢?
我现在能理解是先去找中间件, 中间件可能一般通过 next() 跳出,
跳出之后继续找中间件, 这时遇到作为中间件传的 app.get() 生成的路由..
那这个是不是错了?...
两者顺序怎么样, 如果遍历中间件找不到是不是调用 connect 的 404 操作了?
真的理解错了... 谢谢指导, 现在明白过来了
原来 app.router 是单独的一个和 middleware 平级的对象
http://nodejs.iteye.com/blog/1594920
app.use(express.logger(...));
app.use(express.bodyParser(...));
app.use(express.cookieParser(...));
app.use(express.session(...));
app.use(app.router);
app.use(express.static(...));
app.use(express.errorHandler(...));
@jiyinyiyong


