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),如果是比较耗时的操作,岂不是白白消耗性能了。求大神解答。


5 回复

好的,让我们来分析一下这个问题。

问题描述

你提到的代码中,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) 被执行了两次,那么可以确认是客户端发起了两次请求。如果希望避免这种行为,可以检查客户端代码或网络配置。


每个页面默认都会再发一个/favicon.ico

var http=require('http');
var i=0;
var req=function(req,res){
	i=i+1;
	console.log(i,req.url);
	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 '/favicon.ico'

通过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可能会被调用多次,但这是正常行为,不需要担心。

如果你的目的是确保某个操作只执行一次,可以考虑在更早的阶段进行处理,或者使用中间件来确保某些逻辑只执行一次。

回到顶部