Node.js getaddrinfo ENOTFOUND

398

当使用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模块。

谢谢阅读。


https://dev59.com/KnVD5IYBdhLWcg3wRpaX#11921896 - Arfan Mirza
根据远程主机,必须使用 var http = require("http");var https = require("https"); - prayagupa
7
"ENOTFOUND"是什么意思? - Charlie Parker
8
@CharlieParker 这是 DNS 错误,意味着地址无法解析。 - Greedo
19个回答

380

Node.jsHTTP 模块文档中: 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字段中。其他答案还建议如果需要SSL,则使用https模块。


3
我的问题在于我的Node.js脚本中向错误的URL发出了请求,并因此抛出了错误。 - Michael J. Calkins
91
总之,简单概括一下:1. 在“host”属性中只包括实际的主机名,不要包含“http://”或“https://”;2. 不要在“host”属性中包括路径,而应该在“path”属性中包括路径。 - Eduard Luca
1
我的《学习Node》示例代码没有让我明白这一点。现在我明白了为什么当我填写“options {...}”块时会出现奇怪的失败。 - Michael Shopsin
请确保端口也在与主机不同的选项属性中。 - Lukas Lukac
正如@Jorge Bucaran在另一个答案中所述:在option.host定义中不包括http://是非常重要的(这是我错误的主要原因)。 - Deunz
1
我在主机中包含了 https://,去掉它有助于解决问题。谢谢 @yuxhuang - shary.sharath

285

Another common source of error for

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

在设置options中的host属性时,编写协议(https, http, ...)。

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

7
这个错误比讨论的那个更普遍。 - shaunakde
谢谢@Jorge,我正在使用http.request(),它抛出了错误,我本来要使用http.get(),但我只是用http.request()替换了http://,然后就可以工作了。 - Shashikant Pandit
在我的情况下,我想在vitejs打包程序中获取APP_URL环境变量,但是出现了错误。因此,我删除了协议“http/https”,然后它就可以工作了。 - Bariq Dharmawan
好建议!那么,协议应该在哪里指定呢? - undefined

27

我的问题是我的OS X(Mavericks)DNS服务需要重新启动。在Catalina和Big Sur上,可以通过以下方式清除DNS缓存:

sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder

较旧的 macOS 版本请点击此处查看


22

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

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

我认为那会解决你的问题。


1
谢谢你的回答!这个也完美地解决了问题,但我标记了另一个答案为正确,因为它有文档链接和两个选项。 - Vineet Kosaraju

12

如果需要使用https,则使用 https 库。

https = require('https');

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

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

11
  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
4
仅仅给出代码而不解释问题和解决方案并不是一个完整的答案,我看不懂你在代码块中做了什么,请提供更多说明,谢谢。 - Al-Mothafar

9
我认为即使在选项对象中提供完整的主机URL,http请求也会在80端口上进行。当我在端口3000上运行之前在API上运行的服务器应用程序时,它有效了。请注意,要在80端口上运行应用程序,您需要root权限。
请求错误: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();

这个答案中重要的部分是协议。Node.js的HTTP模块不支持完整的URI,包括host: https://server.com,在这里也有提到:https://dev59.com/TGMm5IYBdhLWcg3wVt0s#28385129。 - prayagupa

6

我用以下方法解决了这个错误

$ 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

这是一个涉及IT技术的问题,关于npm在安装依赖包时的错误。根据该帖子中提到的讨论,似乎该问题可以通过升级node版本来解决。
如果你的npm版本较老,建议先升级npm,然后再尝试安装依赖包。你也可以尝试清除npm缓存并重新安装依赖包。
总之,升级node和npm都是一个不错的选择,因为它们可能会使你遇到的其他问题变得更容易解决。

4
请注意,如果您引用的域名不可用(例如,不存在),也可能出现此问题。

4
在我的情况下,问题是URL格式不正确。我的URL中有双斜杠。

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