Node.js getaddrinfo ENOTFOUND


265

使用Node.js尝试获取以下网页的html内容时:

eternagame.wikia.com/wiki/EteRNA_Dictionary

我收到以下错误:

events.js:72
    throw er; // Unhandled 'error' event
          ^
Error: getaddrinfo ENOTFOUND
    at errnoException (dns.js:37:11)
    at Object.onanswer [as oncomplete] (dns.js:124:16)

我确实已经在stackoverflow上查找了此错误,并意识到这是因为node.js无法从DNS找到服务器(我认为)。但是,我不确定为什么会这样,因为我的代码可以完美地在上工作www.google.com

这是我的代码(实际上是从一个非常类似的问题复制并粘贴的,除了更改了主机):

var http = require("http");

var options = {
    host: 'eternagame.wikia.com/wiki/EteRNA_Dictionary'
};

http.get(options, function (http_res) {
    // initialize the container for our data
    var data = "";

    // this event fires many times, each time collecting another piece of the response
    http_res.on("data", function (chunk) {
        // append this chunk to our growing `data` var
        data += chunk;
    });

    // this event fires *one* time, after all the `data` events/chunks have been gathered
    http_res.on("end", function () {
        // you can use res.send instead of console.log to output via express
        console.log(data);
    });
});

这是我复制和粘贴的来源:如何在Expressjs中进行Web服务调用?

我没有在node.js中使用任何模块。

谢谢阅读。



必须使用var http = require("http");var https = require("https");基于远程主机
祈祷

什么ENOTFOUND 意思
查理·帕克

Answers:


280

Node.js HTTP模块的文档中:http : //nodejs.org/api/http.html#http_http_request_options_callback

您可以调用http.get('http://eternagame.wikia.com/wiki/EteRNA_Dictionary', callback),然后用URL解析url.parse(); 或拨打电话http.get(options, callback),其中options

{
  host: 'eternagame.wikia.com',
  port: 8080,
  path: '/wiki/EteRNA_Dictionary'
}

更新资料

如@EnchanterIO的评论中所述,该port字段也是一个单独的选项。并且该协议http://不应包含在该host字段中。https如果需要SSL,其他答案也建议使用模块。


16
感谢您的快速答复,这非常有效!我觉得我不赞成先阅读文档而对自己的问题不满意。
Vineet Kosaraju

2
我的问题是在我的nodejs脚本中,我向错误的URL发出了请求,并引发了此错误。
Michael J. Calkins 2013年

49
因此,基本上可以归纳为:1.仅在中包含实际的主机名host,因此no http://https://;2.不要在host属性中包含路径,而应在path属性中包含路径。
爱德华·卢卡

1
我在学习节点中的示例代码对我来说并不清楚。现在我明白了为什么我在填写表格时会遇到奇怪的失败options {...}
Michael Shopsin

+确保端口也位于主机的单独选项属性中。
卢卡斯·卢卡奇

240

另一个常见的错误来源

Error: getaddrinfo ENOTFOUND
    at errnoException (dns.js:37:11)
    at Object.onanswer [as oncomplete] (dns.js:124:16)

在中设置属性时正在写协议(https,https,...)hostoptions

  // DON'T WRITE THE `http://`
  var options = { 
    host: 'http://yoururl.com',
    path: '/path/to/resource'
  }; 

7
这是比讨论的错误更普遍的错误。
shaunakde,2015年

5
感谢您发布此替代解决方案,我正好遇到了这个问题。
瑞安

谢谢@Jorge,我正在使用http.request(),该错误引发了与我将要使用http.get()相同的错误,但是我只是使用http.request()删除了http://并开始工作。
Shashikant Pandit

17

在HTTP请求的选项中,将其切换为

var options = { host: 'eternagame.wikia.com', 
                path: '/wiki/EteRNA_Dictionary' };

我认为这可以解决您的问题。


1
感谢你的回答!这也可以正常工作,但是我将另一个标记为正确,因为它具有指向文档的链接和两个选项。
Vineet Kosaraju

12
  var http=require('http');
   http.get('http://eternagame.wikia.com/wiki/EteRNA_Dictionary', function(res){
        var str = '';
        console.log('Response is '+res.statusCode);

        res.on('data', function (chunk) {
               str += chunk;
         });

        res.on('end', function () {
             console.log(str);
        });

  });

感谢你的回答!就像Russbear的答案一样,此方法非常有效,但我标记了yuxhuang的正确性,因为他同时给出了选项和文档链接。
Vineet Kosaraju

1
只是编写代码而没有解释问题和解决方案并不是真正的完整答案,我看不到您在代码块中所做的事情,谢谢。
Al-Mothafar

11

如果需要使用https,请使用https库

https = require('https');

// options
var options = {
    host: 'eternagame.wikia.com',
    path: '/wiki/EteRNA_Dictionary'
}

// get
https.get(options, callback);


7

我认为http在端口80上发出了请求,即使我在options对象中提到了完整的主机URL。当我在以前在端口3000上运行的端口80上运行具有API的服务器应用程序时,它起作用了。请注意,要在端口80上运行应用程序,您将需要root特权。

Error with the request: getaddrinfo EAI_AGAIN localhost:3000:80

这是完整的代码段

var http=require('http');

var options = {
  protocol:'http:',  
  host: 'localhost',
  port:3000,
  path: '/iso/country/Japan',
  method:'GET'
};

var callback = function(response) {
  var str = '';

  //another chunk of data has been recieved, so append it to `str`
  response.on('data', function (chunk) {
    str += chunk;
  });

  //the whole response has been recieved, so we just print it out here
  response.on('end', function () {
    console.log(str);
  });
}

var request=http.request(options, callback);

request.on('error', function(err) {
        // handle errors with the request itself
        console.error('Error with the request:', err.message);        
});

request.end();

这个答案的重要部分是协议。nodejs http不支持带有的完整uri host: https://server.com,在此处也提到了stackoverflow.com/a/28385129/432903
祈祷


3

我用这个解决了这个错误

$ npm info express --verbose
# Error message: npm info retry will retry, error on last attempt: Error: getaddrinfo ENOTFOUND registry.npmjs.org registry.npmjs.org:443
$ nslookup registry.npmjs.org
Server:     8.8.8.8
Address:    8.8.8.8#53

Non-authoritative answer:
registry.npmjs.org  canonical name = a.sni.fastly.net.
a.sni.fastly.net    canonical name = prod.a.sni.global.fastlylb.net.
Name:   prod.a.sni.global.fastlylb.net
Address: 151.101.32.162
$ sudo vim /etc/hosts 
# Add "151.101.32.162 registry.npmjs.org` to hosts file
$ npm info express --verbose
# Works now!

原始来源:https : //github.com/npm/npm/issues/6686



1

我使用request模块进行了尝试,并且能够很容易地打印出该页面的正文。不幸的是,凭借我的技能,我无能为力。


感谢您提供的模块链接,但我希望使用http.get()在标准的node.js库中进行此操作。
Vineet Kosaraju

0

从开发环境转到生产环境时出现此错误。我迷上了https://所有链接。这不是必需的,因此它可能是某些解决方案。



0

如果仍然要面对代理设置的结帐,对我来说就是代理设置丢失了,由于直接的HTTP / https被阻止而无法发出请求。因此,我在发出请求时从我的组织配置了代理。

npm install https-proxy-agent 
or 
npm install http-proxy-agent

const httpsProxyAgent = require('https-proxy-agent');
const agent = new httpsProxyAgent("http://yourorganzation.proxy.url:8080");
const options = {
  hostname: 'encrypted.google.com',
  port: 443,
  path: '/',
  method: 'GET',
  agent: agent
};

0

通过从连接密码中删除不想要的字符,我解决了此问题。例如,我有以下字符:<##%,它引起了问题(很可能是哈希标签是问题的根本原因)。



0

我的问题是我们正在解析url并为http.request()生成http_options;

我使用的request_url.host已经具有域名的端口号,因此必须使用request_url.hostname。

var request_url = new URL('http://example.org:4444/path');
var http_options = {};

http_options['hostname'] = request_url.hostname;//We were using request_url.host which includes port number
http_options['port'] = request_url.port;
http_options['path'] = request_url.pathname;
http_options['method'] = 'POST';
http_options['timeout'] = 3000;
http_options['rejectUnauthorized'] = false;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.