我最近开始使用node.js,express& MongoDB的。由于express使用connect来提供中间件支持,我开始阅读中间件并连接。
我在howtonode.org上看到了以下示例:
return function logItHandle(req, res, next) {
var writeHead = res.writeHead; // Store the original function
counter++;
// Log the incoming request
console.log("Request " + counter + " " + req.method + " " + req.url);
// Wrap writeHead to hook into the exit path through the layers.
res.writeHead = function (code, headers) {
res.writeHead = writeHead; // Put the original back
// Log the outgoing response
console.log("Response " + counter + " " + code + " " + JSON.stringify(headers));
res.writeHead(code, headers); // Call the original
};
// Pass through to the next layer
next();
};
有人可以向我解释这个关闭中发生了什么吗?作者称之为
包含成语以挂钩对writeHead
的调用
这是什么意思?
答案 0 :(得分:3)
它正在拦截对res.writeHead
的调用,添加一些日志记录,然后将调用委托给原始res.writeHead
。
对于方法拦截来说,这就像是一个超级简单的AOP。
答案 1 :(得分:1)
让我们分解这里发生的事情
wrapping idiom to hook into the call to writeHead
在标准 express 流程中,收到请求( req )并准备响应( res )。 ( req , res )对可以通过一系列过滤器进行级联,这些过滤器可以修改 req 并准备 res 强>
在流程中的某一点, res 将被视为充分准备好响应的标头可以发送到客户端。将为此目的调用 res.writeHead *函数。
这个函数的原型是函数(代码,头文件),为了记录要发送的头文件,你需要在这个时刻挂钩代码并做一个< / p>
console.log("Response " + code + " " + JSON.stringify(headers));
在某种程度上,如果代码中的orgininal函数是
res.writeHead = function(code, headers) {
// original code
}
您想用
替换此代码res.writeHead = function(code, headers) {
console.log("Response " + code + " " + JSON.stringify(headers));
// original code
}
在某种程度上,您希望在writeHead函数的开头“插入”一段代码。
但是你不应该尝试修改原始的writeHead代码,因为你甚至可能不知道这段代码的编写地点,也不想开始查找。所以你想要劫持这个函数:当一段代码调用res.writeHead时,你需要调用你的函数。
这样做的方法就是
return function logItHandle(req, res, next) {
res.writeHead = function (code, headers) {
console.log("Response " + code + " " + JSON.stringify(headers));
}
next();
}
但如果你只是这样做,你会遇到一些麻烦,因为原来的writeHead代码丢失了,不会被调用。因此,标题将被记录,但不会发送给客户端!
你需要一种方法来“记住”原始代码并在writeHead变体的末尾调用它:
return function logItHandle(req, res, next) {
// save the original writeHead function so that it can be referenced in the closure
var originalWriteHead = res.writeHead;
res.writeHead = function (code, headers) {
// log the response headers
console.log("Response " + code + " " + JSON.stringify(headers));
// make as if our hook never existed in the flow
res.writeHead = originalWriteHead ;
// call the original writeHead because otherwise the external code
// called our implementation of writeHead instead of the original code
res.writeHead(code, headers);
}
next();
}