为什么这条快速路线会开火几次?

时间:2019-01-15 13:29:25

标签: node.js express try-catch

我有一个从客户端页面调用的服务器路由,如下所示:

$.get("/feed", {
  feedurl: feedUrl,
  dataType: 'json'
}, function() {
  $feedBody.empty();
}).fail(function(error) {
  console.log('ERROR!!');
}).done(function(data) {
    ...
}

这是路线的代码:

router.get('/feed', function(req, res) {

  console.log('getFeed (%s)', req.query.feedurl);

  var myreq = request(req.query.feedurl);

  myreq.on('error', function(error) {
    console.log('DNS Error (%s) [%s]',req.query.feedurl, error.message);
    res.send({error:error.message});
    })
    .on('response', function(response) {
      console.log('RESPONSE (%s) [%s]', req.query.feedurl, JSON.stringify(response));

      if (response.statusCode == 200) {

        getFeed(req.query.feedurl, function (err, feedItems, feedTitle, feedLink) {
          if (feedItems) {
            try {
              console.log('Sending (%s) - %s', req.query.feedurl, new Date().getTime());
              res.send({
                feedItems: feedItems,
                feedLink: feedLink,
                feedTitle: feedTitle
              });
            } catch(err) {
              console.log('ERROR in SEND try / catch (%s) (%s)', req.query.feedurl, err);
            }

          } else {
            res.send({error:err});
          }

        });

      }
    });
});

它可以正常工作,除非不是这样:现在,在特定的URL(显然是gzip编码的RSS提要,但这不是重点)上,该提要被发送回了几(3!)次回到客户端,触发可怕的“发送头后无法设置头”。错误。现在,我无法将错误消息发送回客户端。

以下是上面代码工作时的输出:

2019-01-15 14:23: getFeed (http://rss.nytimes.com/services/xml/rss/nyt/World.xml)
2019-01-15 14:23: Sending (http://rss.nytimes.com/services/xml/rss/nyt/World.xml) - 1547558586803

如果没有,则:

2019-01-15 14:31: getFeed (https://www.rollingstone.com/music/rss)
2019-01-15 14:31: Sending (https://www.rollingstone.com/music/rss) - 1547559093110
2019-01-15 14:31: Sending (https://www.rollingstone.com/music/rss) - 1547559093110
2019-01-15 14:31: ERROR in SEND try / catch (https://www.rollingstone.com/music/rss) (Error: Can't set headers after they are sent.)
2019-01-15 14:31: Sending (https://www.rollingstone.com/music/rss) - 1547559093111
2019-01-15 14:31: ERROR in SEND try / catch (https://www.rollingstone.com/music/rss) (Error: Can't set headers after they are sent.)

请注意3个呼叫以及随后两个已捕获的错误。

仅此路径有一个呼叫;为什么会把东西寄回3次?

1 个答案:

答案 0 :(得分:0)

确定;从this answer中,我了解到有一个res.headersSent布尔值available。另外,根据this one,我必须通过在每个return;之后紧接着res.send()来实施它。

这是我的最终代码:

router.get('/feed', function(req, res) {

  var dnsreq = request(req.query.feedurl);

  dnsreq
    .on('error', function(error) {
      // The only way so far to catch a DNS error
      res.send({error:error.code});
    })
    .on('response', function(response) {

      getFeed(req.query.feedurl, function (err, feedItems, feedTitle, feedLink) {

        if (feedItems && !res.headersSent) {
          res.send({
            feedItems: feedItems,
            feedLink: feedLink,
            feedTitle: feedTitle
          });
          return;

        } else if (!res.headersSent) {
          res.send({error:err});
        }
      });
    });
});