终于登上来了+2,问个问题:Nodejs相关疑问

终于登上来了+2,问个问题:Nodejs相关疑问

/* 我是新手,写了一个小程序统计页面被访问的次数,但是发现一个奇怪的问题。 每次访问页面。sum都会输出两次,最后导致的结果就是第一次显示:你是第1个,刷新一下页面,显示:你是第3个,你是第5个… 我的问题是为什么一次访问似乎会触发两次request事件? 求大虾解惑~~ */ var http = require(‘http’); var server = http.createServer(); server.listen(3333, “127.0.0.1”); var sum = 0; var data = “”; server.on(“request”, function(request, response) { data = "你是第 " + (++sum) + “个.”; console.log(sum); response.writeHead(200, { ‘Content-Type’: ‘text/html;charset=utf-8’, ‘Content-Length’: Buffer.byteLength(data) }); response.write(data , “utf8”); response.end(); });


5 回复

好的,让我们来分析并解决你遇到的问题。你提到每次访问页面时 sum 变量都会增加两次,导致页面显示的数字不是预期的那样。这通常是因为请求被多次处理了。

分析原因

  1. 多重请求:可能是因为浏览器自动发送了两次请求,例如一次是主页面请求,另一次是 favicon 请求。
  2. 网络代理或中间件:某些网络代理或中间件可能会重复处理请求。
  3. 服务器配置问题:某些服务器配置可能导致请求被多次转发。

解决方案

你可以通过检查请求路径来排除一些常见的问题。例如,如果请求路径包含 /favicon.ico,那么可以忽略这些请求。

示例代码

下面是修改后的代码,增加了对 /favicon.ico 路径的过滤:

var http = require('http');

// 创建 HTTP 服务器
var server = http.createServer();

// 监听端口
server.listen(3333, "127.0.0.1");

// 初始化计数器
var sum = 0;

// 处理请求
server.on("request", function(request, response) {
    // 检查请求路径是否为 /favicon.ico
    if (request.url === '/favicon.ico') {
        response.writeHead(404);
        response.end();
        return;
    }

    // 增加计数器
    sum++;
    
    // 构造响应数据
    var data = "你是第 " + sum + " 个.";

    console.log(sum);

    // 设置响应头
    response.writeHead(200, {
        'Content-Type': 'text/html;charset=utf-8',
        'Content-Length': Buffer.byteLength(data)
    });

    // 发送响应数据
    response.write(data, "utf8");
    response.end();
});

解释

  1. 检查请求路径:通过检查 request.url 是否为 /favicon.ico 来排除浏览器自动发送的 favicon 请求。
  2. 增加计数器:只有在请求路径不是 /favicon.ico 时才增加 sum
  3. 设置响应头:设置响应头以确保响应正确。

这样,你的程序应该不会再出现 sum 增加两次的情况,从而避免了显示错误的数字。希望这能帮助你解决问题!


在方法内部加上这句代码你就明白了:

console.log(request.url);

因为你每次刷新你的浏览器会有两个请求过去,

favicon.ico是浏览器默认请求的,用来显示网站的图标,判断url不等于/favicon.ico就行了

ico 事件

你的问题是因为http.createServer()创建的服务器实例默认没有绑定任何路由处理逻辑,因此当客户端请求到达时,默认情况下会触发两次请求事件。这可能与你的客户端(浏览器或测试工具)的行为有关,例如某些浏览器可能会发送两个请求,一个用于获取页面,另一个可能是 favicon.ico 请求。

你可以通过在 createServer 中传入一个回调函数来确保每个请求只处理一次。另外,为了避免重复计数的问题,建议将计数器存储在一个持久化的地方,比如数据库或文件系统中。

以下是一个修改后的示例代码:

var http = require('http');

// 创建服务器并绑定处理逻辑
var server = http.createServer(function (request, response) {
    var filePath = __dirname + '/counter.txt';
    // 读取当前计数器值
    fs.readFile(filePath, 'utf8', function (err, data) {
        if (err) {
            console.error("Error reading counter file:", err);
            data = '0';  // 如果读取失败,设置初始值为0
        }
        var sum = parseInt(data, 10) || 0;

        // 更新计数器值
        sum++;
        fs.writeFile(filePath, sum.toString(), function (err) {
            if (err) {
                console.error("Error writing counter file:", err);
            }
        });

        // 发送响应数据
        response.writeHead(200, {
            'Content-Type': 'text/html;charset=utf-8',
            'Content-Length': Buffer.byteLength(`你是第 ${sum} 个.`)
        });
        response.write(`你是第 ${sum} 个.`);
        response.end();
    });
});

server.listen(3333, "127.0.0.1");
console.log("Server running at http://127.0.0.1:3333/");

在这个示例中,我们将计数器存储在本地文件系统中的 counter.txt 文件里,以避免每次请求时计数器被重复增加。每次请求时,程序会先读取该文件,更新计数器值后再写回文件,并发送响应给客户端。这样可以确保计数器的准确性。

回到顶部