【问题标题】:Override res.write in NodeJS在 NodeJS 中覆盖 res.write
【发布时间】:2011-07-19 09:37:38
【问题描述】:

我玩 NodeJS 已经有一段时间了,我真的很享受它,但是我却碰壁了……

我正在尝试创建一个连接模块来拦截 http.ServerResponse 方法。我的最终目标是允许用户对传出数据应用某种过滤器。例如,他们可以选择在数据流出之前应用压缩或其他方式。

虽然我遇到了这个奇怪的错误...这个方法被调用的频率是它应该被调用的两倍。

这是我的代码:

var http = require('http'), orig;

orig = http.ServerResponse.prototype.write;

function newWrite (chunk) {
    console.log("Called");

    orig.call(this, chunk);
}

http.ServerResponse.prototype.write = newWrite;

http.createServer(function (req, res) {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.write("Hello");
    res.write(" World");
    res.end();
    console.log("Done");
}).listen(12345);

这很有效,当我使用浏览器访问它时,我得到了“Hello World”作为输出,但是我得到了 4 个“Called”到控制台,并且“Done”得到了两次输出。这让我相信由于某种原因,我的服务器代码被调用了两次。我在 this.constructor 上的 newWrite 方法中做了一个 console.log,两个实例中的构造函数都是 ServerResponse,所以没有多大帮助。

我真的很困惑这里发生了什么。可能会发生什么?这不会直接影响输出,但我可能会同时向许多客户端提供千兆字节的压缩数据,并且两次执行所有操作会给我的服务器带来过度的压力。

这将成为更大文件服务器的一部分,因此强调不要将所有事情都做两次。

编辑:

如果您想知道,我已经阅读了这个问题:

Can I use an http.ServerResponse as a prototype in node.js?

【问题讨论】:

    标签: javascript http stream node.js connect


    【解决方案1】:

    你可以使用 connect 的 favicon 中间件来避免这个问题:

    http://senchalabs.github.com/connect/middleware-favicon.html

    【讨论】:

      【解决方案2】:

      您的代码没有问题:如果您在createServer 调用中添加console.log(req.url),您可能会看到它实际上被浏览器调用了两次。如果在 html 标记中未指定网站图标,大多数浏览器都会对请求的 url 发出请求,并附加调用/favicon.ico

      【讨论】:

      • 这更有意义!像 curl 这样的命令行实用程序可以做到这一点吗?考虑到他们不使用图标,我不这么认为。我想我在生产中不必担心这一点,因为静态文件的代码路径与查询的代码路径不同。
      • No CURL 不会,但浏览器会请求它们。您可以在标记中禁用它们。
      猜你喜欢
      • 2022-10-05
      • 2015-09-03
      • 2014-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-22
      相关资源
      最近更新 更多