【问题标题】:Express / NodeJS Can't send headers after they are sent caused by http requestsExpress / NodeJS由于http请求导致发送后无法发送标头
【发布时间】:2011-10-19 15:12:36
【问题描述】:

第一次使用 NodeJS(是的,它很棒)并且还使用了 Express。让网络应用程序/服务运行良好,但在尝试发出多个 http 请求时遇到了问题。这是该应用程序如何导致 2 个 http 请求的视频 - http://screencast.com/t/yFKdIajs0XD - 如您所见,我单击“文章”它加载了一个 rss 提要,然后单击视频并加载了一个 youtube 提要-两者都可以正常工作,但在第二个之后调用它会引发异常。当我使用节点的 http 模块尝试两个单独的 http 请求时,我得到以下信息:

http.js:527
throw new Error("Can't set headers after they are sent.");
      ^

Error: Can't set headers after they are sent.
at ServerResponse.<anonymous> (http.js:527:11)
at ServerResponse.setHeader (/Users/rickblalock/node/auti_node/node_modules/express/node_modules/connect/lib/patch.js:47:22)
at /Users/rickblalock/node/auti_node/node_modules/express/node_modules/connect/lib/middleware/errorHandler.js:72:19
at [object Object].<anonymous> (fs.js:107:5)
at [object Object].emit (events.js:61:17)
at afterRead (fs.js:878:12)
at wrapper (fs.js:245:17)

此处提供的示例代码: 使用我的控制器模块来呈现请求 - http://pastie.org/2317698 选项卡之一(文章选项卡) - 视频代码相同减去引用视频源:http://pastie.org/2317731

【问题讨论】:

    标签: http node.js request express


    【解决方案1】:

    尝试像这样使用“结束”事件而不是“数据”:

    var data = "";
    
    app.get('/', function(req, res){
    
        var options = {
              host: 'http://www.engadget.com',
              path: '/rss.xml',
              method: 'GET'
            };
    
        if (data === "") {
            var myReq = http.request(options, function(myRes) {
                myRes.setEncoding('utf8');
    
                myRes.on('data', function(chunk) {
                    console.log("request on data ");
                    data += chunk;
                });
    
                myRes.on('end', function () {
                    console.log("request on END");
                    res.render('index', {
                        title: 'Express',
                        data: data
                    });
                });
            });
    
            myReq.write('data\n');
            myReq.end();
        }
        else {
            res.render('index', {
                title: 'Express',
                data: data
            });
        }
    });
    

    旧答案

    我也认为这是罪魁祸首:

    var req = http.request(options, function(res) {
        res.setEncoding('utf8');
        res.on('data', function(chunk) {
          parseArticle(chunk);
        });
    });
    req.write('data\n');
    req.end();
    

    第一行是异步的,所以在你执行req.write()req.end() 之后调用回调中的所有内容 将这两行放入回调中。

    【讨论】:

    • NodeJS 文档中的示例就是这样。有道理为什么。但是,看起来我无论如何都不应该做 write() 的事情。
    • @pkyeck -- 我也想知道这一点。但请注意,回调不引用“req”(只是“res”),因此在处理“res”之前结束“req”可能是正确的。
    • 我从来没有使用过 http.request() 函数——你从其他地方提取数据,不是吗?!但你永远不会得到数据,因为你在那之前结束了 req ...
    • @rick-blalock 好的,构建了一个小示例,上面的代码正在运行。我认为问题可能是您解析有关数据事件的文章 - 尝试“结束”。
    • 解析结束事件对我有用。谢谢!另外,我刚开始使用 request 模块,它是 node 附带的 http 模块的一个很好的桥梁。
    猜你喜欢
    • 2017-03-03
    • 1970-01-01
    • 2018-07-29
    • 1970-01-01
    • 2013-01-03
    • 2015-12-20
    • 2016-09-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多