Почему этот экспресс-маршрут запускается несколько раз? - PullRequest
0 голосов
/ 15 января 2019

У меня есть серверный маршрут, который вызывается со страницы клиента, например:

$.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 (очевидно, в RSS-канале с кодировкой gzip, но это не совсем так), фид отправляется обратно несколько (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 голосов
/ 15 января 2019

ОК; Из этого ответа я узнал, что есть res.headersSent логическое доступное . Кроме того, согласно этому , я должен был применять его 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});
        }
      });
    });
});
...