【问题标题】:Node.js Https request ErrorNode.js Https 请求错误
【发布时间】:2013-10-22 04:13:13
【问题描述】:

我试过the sample from the documentation,效果很好。

但是当我将 URL 更改为 https://api.mercadolibre.com/sites/ 时,请求挂起。我唯一得到的是:

{ [Error: socket hang up] code: 'ECONNRESET' }

这是我的代码:

var https = require('https');

this.dispatch = function(req, res) {
  var renderHtml = function(content) {
    res.writeHead(200, {'Content-Type': 'text/html'});
    res.end(content, 'utf-8');
  }

  var parts = req.url.split('/');

  var options = {
    host: 'api.mercadolibre.com',
    port: 443,
    path: '/sites/',
    method: 'GET'
  };

  var request = https.request(options, function(res) {
    console.log("statusCode: ", res.statusCode);
    console.log("headers: ", res.headers);

    res.on('data', function(d) {
      process.stdout.write(d);
    });
  });

  request.on('error', function(e) {
    console.error('error');
    console.error(e);
  });

  request.end();
  return 'item id:' + parts[2];
};

我尝试过使用 curl、soapui 和浏览器。在所有情况下都很好用,但使用 node.js 就不行了。

我怎样才能获得更多关于正在发生的事情的数据?

添加

我使用 curl: curl --sslv3 https://api.mercadolibre.com/sites/ 有效。 我在centos 6中测试过同样的东西并且也可以工作。 我已经从源头重新安装了节点,同样的问题。我的操作系统是 ubuntu 12.04。 谢谢。

【问题讨论】:

  • 您需要向我们展示您正在使用的设备,以便我们诊断问题。

标签: node.js https


【解决方案1】:

我不确定api.mercadolibre.com 站点,但如果我删除port 参数,我可以调用API,如下代码:

var options = {
    host: 'api.mercadolibre.com',
    path: '/sites/',
    method: 'GET'
};

我们还需要添加参数来支持 SSL 版本 3:

https.globalAgent.options.secureProtocol = 'SSLv3_method';

【讨论】:

  • SSLv3_method 帮助我解决了一个 2 年前的问题!非常感谢!
【解决方案2】:

为什么不使用像request 这样的库来为您处理细节?

var request = require('request');

request('https://api.mercadolibre.com/sites/', {}, function(err, res, body) {
  console.log("Got body: ", body);
});

这会产生:

Got body:  [{"id":"MLA","name":"Argentina"},{"id":"MLB","name":"Brasil"},{"id":"MCO","name":"Colombia"},{"id":"MCR","name":"Costa Rica"},{"id":"MEC","name":"Ecuador"},{"id":"MLC","name":"Chile"},{"id":"MLM","name":"Mexico"},{"id":"MLU","name":"Uruguay"},{"id":"MLV","name":"Venezuela"},{"id":"MPA","name":"Panamá"},{"id":"MPE","name":"Perú"},{"id":"MPT","name":"Portugal"},{"id":"MRD","name":"Dominicana"}]

【讨论】:

  • 一模一样。我怎样才能获得更多关于正在发生的事情的数据?
  • 当您说“完全相同”时,您的意思是您又看到了{ [Error: socket hang up] code: 'ECONNRESET' }?听起来他们可能会阻止来自您的 IP 的访问,或者其他什么。
  • 是的,完全一样。我不认为有什么东西阻止了我的 ip,也许有什么东西阻止了 node.js 请求。现在我在节点脚本中执行 curl(并且可以工作),同时我意识到会发生什么。有没有办法获得更多信息,了解是什么阻止了我的请求?
  • 使用request 对我来说效果很好。再迈一步。 body 将我的数据打印为字符串,我需要像这样将其转换为 json JSON.parse(body)
【解决方案3】:

由于它使用 curl,请尝试使用 node-curl 模块。在我切换到 node-curl 之前,我花了一整天的时间试图让它在 node.js 中使用 http 和/或 https 模块工作。

试试这个:

var curl = require('node-curl');
curl('https://api.mercadolibre.com/sites/', {SSLVERSION: 3}, function(err, res) {
    var body = res.body;
    res.close();
    console.log(body);
});

【讨论】:

    【解决方案4】:

    这里也一样,使用 curl 但不使用 node.js。

    问题:在 CentOS-5 上 curl 使用提供 openssl 库,因此使用 centos 标准 /etc/pki/tls/certs/ca-bundle.crt 进行 CA 检查。

    node.js 在哪里寻找?,通过 strace,我看不到任何对 CA 文件的引用以进行检查。 接受来自知名旧发行者的具有有效 SSL 证书的服务器的 Node.js 请求,但不接受具有自己 CA 的我自己的网络服务器。 我将自己的 CA.crt 放在 ca-bundle.crt 文件中,所以现在 curl 接受它,但不是 node.js。

    目前唯一的解决方案是停用我的 dev-box 的验证检查:

        var client = require('https');
        var download_options = url.parse(sourceUrl);
        download_options.method = "GET";
        download_options.agent = false;
        download_options.rejectUnauthorized = false; / HERE to accept all SSL-certificates */
    
        var download_request = client.request(download_options);
    

    【讨论】:

      【解决方案5】:

      我认为您使用了需要指定请求的代理。代理设置由 node-curl 使用的 libcurl 自动检测。因此请求在 node-curl 中传递。

      因此,找出您的组织使用的代理 IP 和端口,然后试试这个:

      var request = require('request');
      request({
          uri : 'https://mail.google.com/mail',
          proxy : 'http://<proxy ip>:<proxy port>'
      }, function (error, response, body) {
          if (!error && response.statusCode == 200) {
              console.log(body) // Print the google web page.
          }else{
              console.log(error);
              console.log(response.statusCode);
          }
      })
      

      【讨论】:

        【解决方案6】:

        如果您这样做,您将收到 ECONNRESET 错误:

        post_options.path = 'history';
        ...
        var req = http.request(post_options, function(res) {
        ...
        

        也就是说,你需要确保你的路径有这样的 /

        post_options.path = '/history';
        ...
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-12-26
          • 2019-01-24
          • 1970-01-01
          • 2018-11-15
          • 2016-09-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多