【问题标题】:Error can't set headers after they are sent. (res.send())发送后无法设置标头错误。 (res.send())
【发布时间】:2017-09-06 16:27:17
【问题描述】:

我正在为一个错误而苦苦挣扎,如果可能的话,我希望得到帮助。我需要从我的路由器发送一个数组:发音/路由:/words 到一个 javaScript 文件,该文件向该路由(“/words”)发送一个带有(询问)之类的单词的数组。

所以在那个路由(“/words”)中,我向 API 请求单词(ask),然后我可以从数据库中获取它的所有值。

然后我将一个数组发送回文件,该文件由“return res.send(array)”开始。好吧,确实有效。但是我的问题从发送到路由器/路由的数组中有两个单词开始,即使请求运行良好并且我能够从 API 中获取这些单词的信息,例如(ask,a),当它运行“return res.send(array)”行我有一条消息错误说“错误在发送后无法设置标题。”

这样的解释是否足以让人理解?

提前致谢!

router.get("/words", function(req, res) {
    var wordsToBeSearched = req.query.str;
    var dictionary = [];
    for(var i = 0; i < wordsToBeSearched.length; i++) {
        var url = "http://www.dictionaryfake.com/api/xml/" + wordsToBeSearched[i];
        request(url, function(error, response, body) {
            if(!error && response.statusCode == 200) {
                parseString(body, function (err, result) {
                    var word = (JSON.stringify(result["entry_list"]["entry"][0]["ew"][0]));
                    var sound = (JSON.stringify(result["entry_list"]["entry"][0]["sound"][0]["wav"][0]));
                    var symbol = (JSON.stringify(result["entry_list"]["entry"][0]["pr"][0]));
                    var singleWord = {word: word.replace(/"/g,''), symbol: symbol.replace(/"/g,''), sound: sound.replace(/"/g,'')};
                    dictionary.push(singleWord);

                    if(i === wordsToBeSearched.length) {
                        return res.send(dictionary);
                    };
                };
             };
         };
    };
};

enter image description here

【问题讨论】:

  • 我们必须查看代码的相关部分才能帮助您解决此错误。这种类型的错误通常是您在处理异步请求时的错误,但是为了准确地告诉您需要修复什么,我们需要查看您的实际代码。由于您是新来的,关于代码的问题必须包含相关代码。我们在 stackoverflow 上回答显示正在使用的实际代码的特定问题的效率比我们回答可能有数千个可能原因的理论问题的效率高出大约 100 倍。
  • 您在评论中有一些有用的代码,但格式错误。尝试编辑您的问题并将代码放入问题中。基本问题是您在for 循环中调用res.send,这意味着它被多次调用。
  • 并且,请使用您问题下方的“编辑”链接将代码添加到您的问题中,然后正确格式化。 cmets 中的多行代码通常不可读,无论如何代码都应该在问题本身中。这是堆栈溢出时的how to format code
  • @jfriend00 并感谢您的建议,我编写了路线的代码,是的,我正在使用异步请求,如果你们也需要那段代码,请告诉我。再次感谢!

标签: javascript node.js express


【解决方案1】:

您希望等待所有请求完成,然后将字典返回给您。 这可以使用(异步)promises 很好地完成。您可以执行多个 Promise 并等待它们全部解决,然后再res.send发送结果。

router.get("/words", function(req, res) {
  var wordsToBeSearched = req.query.str;
  var dictionary = [];
  var requests = [];

  for(var i = 0; i < wordsToBeSearched.length; i++) {
    var req = new Promise((resolve, reject) => {
      var url = "http://www.dictionaryfake.com/api/xml/" + wordsToBeSearched[i];

      request(url, function(error, response, body) {
        if (error || !response.statusCode === 200) {
          reject(error);
        } else {
          parseString(body, function (err, result) {
            var word = (JSON.stringify(result["entry_list"]["entry"][0]["ew"][0]));
            var sound = (JSON.stringify(result["entry_list"]["entry"][0]["sound"][0]["wav"][0]));
            var symbol = (JSON.stringify(result["entry_list"]["entry"][0]["pr"][0]));
            var singleWord = {word: word.replace(/"/g,''), symbol: symbol.replace(/"/g,''), sound: sound.replace(/"/g,'')};
            dictionary.push(singleWord);
            resolve();
          });
        }
      });
    });
    requests.push(req);
  }

  Promise.all(requests)
    .then(() => {
      res.send(dictionary);
  })
  .catch(err => console.error(err));
});

【讨论】:

  • 非常感谢,现在可以正常使用了。也感谢承诺:)
猜你喜欢
  • 2015-12-25
  • 2017-11-24
  • 1970-01-01
  • 2018-06-08
  • 2018-06-29
  • 2013-12-22
  • 1970-01-01
相关资源
最近更新 更多