Node.js Https请求错误

8

我尝试过文档中的示例,它工作得很好。

但是当我将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上测试也可以工作。 我重新安装了node,这次从源代码安装,但是问题依旧。我的操作系统是ubuntu 12.04。 谢谢。

你需要向我们展示你正在使用的内容,以便我们可以诊断问题。 - Asherah
6个回答

7

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

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

我们还需要添加参数以支持SSL 3.0版本:

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

2
SSLv3_method 帮助我解决了一个两年的问题!非常感谢! - Fábio Batista

3

因为它正在使用curl,尝试使用node-curl模块。在node.js中使用http和/或https模块让我花了一整天的时间才使其工作,直到我切换到了node-curl为止。

尝试这样做:

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);
});

3
为什么不使用像 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"}]

完全一样的东西。我怎么能获得更多关于正在发生的情况的数据? - Norton Prot
当你说“完全相同的事情”时,你是指再次看到 { [Error: socket hang up] code: 'ECONNRESET' } 吗?听起来他们可能正在阻止你的IP访问或其他什么。 - Asherah
是的,完全没有错。我不认为是因为我的IP被阻止了,可能是有一些东西阻止了node.js的请求。目前,我在节点脚本中执行curl命令(而且它运行良好),同时我在弄清楚发生了什么。有没有办法获取更多关于阻止我的请求的信息? - Norton Prot
使用 request 对我来说很有效。只需再进行一步,body 将我的数据以字符串形式打印出来,我需要将其转换为 JSON,像这样 JSON.parse(body) - Ian Poston Framer

1

我也有同样的问题,使用curl可以工作,但使用node.js却不行。

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

而node.js会在哪里查找呢?通过strace,我无法看到任何关于用于检查的CA文件的引用。 使用有效SSL证书的服务器对node.js的请求被接受,但使用自己的CA的Web服务器就不行。 我将自己的CA.crt放入ca-bundle.crt文件中,这样curl就接受了它,但node.js没有。

目前唯一的解决办法是在我的开发机上停用验证检查:

    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);

0

我想你是在代理后面,需要指定请求的代理设置。libcurl会自动检测代理设置,而node-curl使用它。因此,请求可以通过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);
    }
})

0

如果你这样做,就会收到ECONNRESET错误:

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

也就是说,你需要确保你的路径中有一个/,像这样:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接