Nodejs的一个疑问,为什么req被执行了两次(从控制台输出可看出)
Nodejs的一个疑问,为什么req被执行了两次(从控制台输出可看出)
代码: var http=require(‘http’); var i=0; var req=function(req,res){ i=i+1; console.log(i); res.writeHead(200,{‘Content-Type’:‘text/plain’}); res.end(‘Hello World\n’); };
http.createServer(req).listen(8888,“127.0.0.1”); console.log(‘Server running…’);
控制台输出: Server running… 1 2
从控制台可以看出console.log(i)被执行了两次。只是一个请求,咋会执行两次console.log(i),如果是比较耗时的操作,岂不是白白消耗性能了。求大神解答。
好的,让我们来分析一下这个问题。
问题描述
你提到的代码中,console.log(i)
被执行了两次,尽管你认为只发送了一个请求。这可能是由于客户端的行为或服务器配置导致的。
分析
在你的代码中,http.createServer(req)
创建了一个 HTTP 服务器,并且每次接收到请求时都会调用 req
函数。console.log(i)
的输出次数取决于客户端发送了多少次请求到这个服务器。
示例代码
首先,我们来看一下你的原始代码:
var http = require('http');
var i = 0;
var req = function(req, res) {
i = i + 1;
console.log(i);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
};
http.createServer(req).listen(8888, "127.0.0.1");
console.log('Server running...');
解决方案
为了更好地理解问题,我们可以使用一个更标准的方式来定义路由处理函数,并添加一些调试信息来查看请求的具体情况。
var http = require('http');
// 定义一个路由处理函数
function handleRequest(req, res) {
console.log(`Received request at ${req.url}`);
// 假设我们使用一个计数器来跟踪请求次数
var i = 0;
i++;
console.log(`Request count: ${i}`);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
}
http.createServer(handleRequest).listen(8888, "127.0.0.1");
console.log('Server running...');
解释
在这个修改后的代码中:
- 我们将处理函数命名为
handleRequest
,以避免与req
变量名冲突。 - 添加了
console.log(req.url)
来显示每次请求的 URL,这有助于了解客户端是否发送了多次请求。 - 使用局部变量
i
来记录每个请求的计数,而不是全局变量。
测试
你可以通过浏览器或其他工具(如 Postman 或 curl)向 http://127.0.0.1:8888/
发送请求,并观察控制台输出。如果发现 console.log
输出了两次,那么很可能是客户端发起了两次请求。
结论
如果你看到 console.log(i)
被执行了两次,那么可以确认是客户端发起了两次请求。如果希望避免这种行为,可以检查客户端代码或网络配置。
通过NODEJS社区(http://webchat.freenode.net/?channels=node.js#),已解决此问题,顺便也在此说明一下
把console.log(i); 改为console.log(i+":"+req.url);即可把此问题看明白了,这时输出为: Server running… 1:/ 2:/favicon.ico
我们发现favicon也被当做是一次请求,故被执行了两次,另外有意思的地方就是把res.end(‘Hello World\n’);注释或删除,console.log(i)就不会被执行两次了。
尽管此问题已解决了,还是感谢TONNY兄
根据你的描述,问题出在req
函数被执行了两次。这通常是因为HTTP请求包含两个部分:一个请求头和一个请求体。客户端发送请求时,首先发送请求头,然后可能发送请求体(如果请求体存在)。服务器端会分别处理这两个部分。
在这个例子中,req
函数被同时处理了请求头和请求体,所以console.log(i)
被执行了两次。你可以通过在代码中添加日志来验证这一点:
var http = require('http');
var i = 0;
var req = function(req, res) {
console.log('Handling request...');
i = i + 1;
console.log('Request count:', i);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
};
http.createServer(req).listen(8888, "127.0.0.1");
console.log('Server running...');
运行上述代码,你会看到每次请求都只会打印一次“Request count:”。如果你使用的是GET请求,通常没有请求体,因此req
只会被调用一次。如果你使用的是POST或PUT等包含请求体的请求类型,req
可能会被调用多次,但这是正常行为,不需要担心。
如果你的目的是确保某个操作只执行一次,可以考虑在更早的阶段进行处理,或者使用中间件来确保某些逻辑只执行一次。