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?

Я не использую никаких модулей с node.js.

Спасибо за прочтение.



пришлось использовать var http = require("http");или var https = require("https");на основе удаленного хоста
praagagupd

что ENOTFOUND значит?
Чарли Паркер

Ответы:


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, и эта ошибка была выдана.
Майкл Дж. Калкинс

49
Итак, в общем, чтобы подвести итог: 1. Включите только фактическое имя хоста в host, поэтому нет http://или https://; и 2. Не включайте путь в hostсвойство, а скорее в pathсвойство.
Эдуард Лука,

1
Мой пример кода в Learning Node не прояснил мне это. Теперь я понимаю, почему у меня возникли странные неудачи, когда я заполнил options {...}блок.
Майкл Шопсин

+ убедитесь, что порт также находится в отдельном атрибуте опции от хоста.
Лукас Лукач

240

Еще один распространенный источник ошибок для

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

записывает протокол (https, https, ...) при установке hostсвойства вoptions

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

7
Это более общая ошибка, чем обсуждаемая.
Shaunakde

5
Спасибо за размещение этого альтернативного решения, я столкнулся с этим точно.
Райан

Спасибо @Jorge, я использую http.request (), который выдавал ошибку так же, как я собирался использовать http.get (), но я просто удалил http: // с помощью http.request () и работал.
Шашикант Пандит

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

  });

Спасибо за ответ! Как и ответ Руссбира, этот работает отлично, но я отметил, что Юйшуан правильный, потому что он дал оба варианта и ссылку на документы.
Vineet Kosaraju

1
Просто код, не объясняя, в чем проблема и какое решение на самом деле не является полным ответом, я не вижу, что вы сделали в своем блоке кода, спасибо.
Аль-Мотафар

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, хотя я упомянул полный URL-адрес хоста в объекте параметров. Когда я запускаю серверное приложение, имеющее API, на порту 80, которое я ранее выполнял на порте 3000, оно работало. Обратите внимание, что для запуска приложения на порту 80 вам потребуются права суперпользователя.

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

важная часть в этом ответе - протокол. http: nodejs не поддерживает полный URI host: https://server.com, который также упоминается здесь: stackoverflow.com/a/28385129/432903
praagagupd

3

Обратите внимание, что эта проблема также может возникнуть, если домен, на который вы ссылаетесь, выходит из строя (например, больше не существует.)


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


2

Я получил ту же ошибку и использовал ниже ссылку для получения справки:

https://nodejs.org/api/http.html#http_http_request_options_callback

У меня не было в моем коде:

req.end();

(NodeJs V: 5.4.0), однажды добавленная выше req.end();строка, я смог избавиться от ошибки и отлично работал для меня.


1

Я попробовал это с помощью модуля запроса и смог довольно легко распечатать тело этой страницы. К сожалению, с моими навыками я не могу помочь, кроме этого.


Спасибо за ссылку на модуль, но я надеялся сделать это с помощью стандартной библиотеки node.js, используя http.get ().
Vineet Kosaraju

0

Я получил эту ошибку при переходе от среды разработки к производственной среде. Я был одержим размещением https://всех ссылок. В этом нет необходимости, поэтому для некоторых это может быть решением.


0

Я избавился от http и дополнительной косой черты (/). Я просто использовал этот «node-test.herokuapp.com», и он работал.


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_options для http.request ();

Я использовал 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;
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.