Node.js:给定 URL 数组,确定哪些是有效的

标签 node.js http asynchronous response

我完全不喜欢 Node http 模块,遇到了一些麻烦。

这里的最终目标是获取一个巨大的 url 列表,找出哪些是有效的,然后从这些页面中抓取某些数据。所以第一步是确定 URL 是否有效,这个简单的练习让我感到困惑。

假设我们有一个数组 allURLs:

["www.yahoo.com", "www.stackoverflow.com", "www.sdfhksdjfksjdhg.net"]

目标是迭代此数组,向每个数组发出获取请求,如果收到响应,则将链接添加到工作 URL 列表(现在只是另一个数组),否则它会转到 brokenURLs 列表。

var workingURLs = [];
var brokenURLs = [];
for (var i = 0; i < allURLs.length; i++) {
  var url = allURLs[i];
  var req = http.get(url, function (res) {
    if (res) {
      workingURLs.push(?????);  // How to derive URL from response?
    }
  });

  req.on('error', function (e) {
    brokenURLs.push(e.host);
  });
}

我不知道的是如何正确地从请求/响应对象本身获取 url,或者实际上如何构建这种异步代码——因为我又是一个 nodejs 擦洗 :(

对于大多数使用 res.headers.location 的网站来说,这是可行的,但有时标题没有此属性,这会在以后给我带来问题。我也尝试过控制台记录响应对象本身,这是一个困惑且毫无结果的尝试

我已经尝试将 url 变量推送到 workingURLs,但是当任何响应返回并触发推送时,for 循环已经结束并且 url 永远指向 allURLs 数组的最后一个元素。

感谢任何能提供帮助的人

最佳答案

您需要关闭 url 值才能访问它并保护它免受下一次循环迭代的更改。
例如:

(function(url){
  // use url here
})(allUrls[i]);

最简单的解决方案是使用 forEach 而不是 for

allURLs.forEach(function(url){
  //....
});

Promisified 解决方案让您在工作完成时得到片刻:

    var http = require('http');
    var allURLs = [
      "http://www.yahoo.com/",
      "http://www.stackoverflow.com/",
      "http://www.sdfhksdjfksjdhg.net/"
    ];
    var workingURLs = [];
    var brokenURLs = [];
    var promises = allURLs.map(url => validateUrl(url)
      .then(res => (res?workingURLs:brokenURLs).push(url)));
    Promise.all(promises).then(() => {
      console.log(workingURLs, brokenURLs);
    });
    // ----
    function validateUrl(url) {
      return new Promise((ok, fail) => {
        http.get(url, res => return ok(res.statusCode == 200))
          .on('error', e => ok(false));
      });
    }

// Prevent nodejs from exit, don't need if any server listen.
var t = setTimeout(() => { console.log('Time is over'); }, 1000).ref();

关于Node.js:给定 URL 数组,确定哪些是有效的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37899964/

相关文章:

c# - 通过计时器以 xamarin 形式重复异步任务

ios - Firebase 在 Swift 中使用 PromiseKit/AwaitKit 调用永远不会返回

javascript - 检查 Steam 游戏 key 字符串

node.js - 如何填充 Mongoose 中的嵌套对象?

node.js - BreezeJS RequireJS 针对生产进行了优化

node.js - 将子域反向代理到同一台机器上的不同端口会抛出 404

c# - 使用 StringContent 访问 HttpResponseMessge 中的 JSON 对象

iphone - iOS 浏览器后退按钮发出 HTTP GET 而不是预期的 POST

html - 无法在golang中很好地执行模板

javascript - Angular.js : Initializing a controller on an asynchronously loaded template?