Node.js getaddrinfo ENOTFOUND


265

Khi sử dụng Node.js để thử và lấy nội dung html của trang web sau:

eternagame.wikia.com/wiki/EteRNA_Dictionary

Tôi nhận được lỗi sau đây:

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)

Tôi đã tìm kiếm lỗi này trên stackoverflow và nhận ra rằng điều này là do node.js không thể tìm thấy máy chủ từ DNS (tôi nghĩ). Tuy nhiên, tôi không chắc tại sao lại như vậy, vì mã của tôi hoạt động hoàn hảo www.google.com.

Đây là mã của tôi (thực tế được sao chép và dán từ một câu hỏi rất giống nhau, ngoại trừ máy chủ đã thay đổi):

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

Đây là nguồn mà tôi đã sao chép và dán từ: Cách thực hiện các cuộc gọi dịch vụ web trong Expressjs?

Tôi không sử dụng bất kỳ mô-đun nào với node.js.

Cảm ơn vì đã đọc.



phải sử dụng var http = require("http");hoặc var https = require("https");dựa trên máy chủ từ xa
nguyện

ENOTFOUND nghĩa là gì
Charlie Parker

Câu trả lời:


280

Trong tài liệu của mô-đun Node.js HTTP : http://nodejs.org/api/http.html#http_http_Vquest_options_callback

Bạn có thể gọi http.get('http://eternagame.wikia.com/wiki/EteRNA_Dictionary', callback), URL sau đó được phân tích cú pháp url.parse(); hoặc gọi http.get(options, callback), nơi options

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

Cập nhật

Như đã nêu trong nhận xét của @EnchanterIO, porttrường này cũng là một tùy chọn riêng biệt; và giao thức http://không nên được bao gồm trong hostlĩnh vực này. Các câu trả lời khác cũng khuyến nghị sử dụng httpsmô-đun nếu cần SSL.


16
Cảm ơn đã trả lời nhanh chóng, điều này hoạt động hoàn hảo! Tôi cảm thấy muốn hạ thấp câu hỏi của chính mình vì đã không đọc tài liệu trước.
Vineet Kosaraju

2
Vấn đề của tôi là trong tập lệnh nodejs của tôi, tôi đã yêu cầu url sai và lỗi này đã bị ném.
Michael J. Calkins

49
Về cơ bản, để tóm tắt: 1. Chỉ bao gồm tên máy chủ thực tế host, nên không http://hoặc https://; và 2. Không bao gồm đường dẫn trong hosttài sản, mà thay vào đó là pathtài sản.
Eduard Luca

1
Mã mẫu của tôi trong Learning Node không làm rõ điều này với tôi. Bây giờ tôi đã hiểu tại sao tôi gặp thất bại kỳ lạ khi tôi điền vào options {...}khối.
Michael Storesin

+ đảm bảo rằng cổng cũng nằm trong một thuộc tính tùy chọn riêng biệt từ máy chủ.
Lukas Lukac

240

Một nguồn lỗi phổ biến khác cho

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

đang viết giao thức (https, https, ...) khi đặt thuộc hosttính trongoptions

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

7
Đây là một lỗi chung hơn so với một lỗi được thảo luận.
shaunakde

5
Cảm ơn bạn đã đăng giải pháp thay thế này, tôi đã chạy vào chính xác này.
Ryan

Cảm ơn @Jorge tôi đang sử dụng http.request () đã ném lỗi tương tự tôi sẽ sử dụng http.get () nhưng tôi đã xóa http: // với http.request () và đã hoạt động.
Pandash Shashikant

17

trong các tùy chọn cho yêu cầu HTTP, hãy chuyển nó sang

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

Tôi nghĩ rằng sẽ khắc phục vấn đề của bạn.


1
Cảm ơn câu trả lời! Điều này cũng hoạt động hoàn hảo, nhưng tôi đã đánh dấu cái kia là chính xác vì nó có liên kết đến các tài liệu và hai tùy chọn.
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);
        });

  });

Cảm ơn câu trả lời! Giống như câu trả lời của Russbear, câu trả lời này hoạt động hoàn hảo nhưng tôi đã đánh dấu chính xác của yuxhuang vì ông đã đưa ra cả hai tùy chọn và liên kết đến các tài liệu.
Vineet Kosaraju

1
Chỉ cần mã mà không giải thích vấn đề gì và giải pháp nào không thực sự là một câu trả lời hoàn chỉnh, tôi không thấy những gì bạn đã làm trong khối mã của mình, cảm ơn.
Al-Mothafar

11

Nếu bạn cần sử dụng https, thì hãy sử dụng thư viện https

https = require('https');

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

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


7

Tôi nghĩ rằng http thực hiện yêu cầu trên cổng 80, mặc dù tôi đã đề cập đến url máy chủ hoàn chỉnh trong đối tượng tùy chọn. Khi tôi chạy ứng dụng máy chủ có API, trên cổng 80, mà tôi đã chạy trước đó trên cổng 3000, nó đã hoạt động. Lưu ý rằng để chạy một ứng dụng trên cổng 80, bạn sẽ cần quyền root.

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

Đây là một đoạn mã hoàn chỉnh

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

phần quan trọng trong câu trả lời này là giao thức. nodejs http không hỗ trợ đầy đủ uri với host: https://server.com, điều này cũng được đề cập ở đây cũng như stackoverflow.com/a/28385129/432903
nguyện

3

Lưu ý rằng vấn đề này cũng có thể xảy ra nếu tên miền bạn đang tham chiếu đi xuống (EG. Không còn tồn tại.)


3

Tôi đã sửa lỗi này với

$ 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!

Nguồn gốc: https://github.com/npm/npm/issues/6686



1

Tôi đã thử nó bằng mô-đun yêu cầu và có thể in phần thân của trang đó ra khá dễ dàng. Thật không may với những kỹ năng tôi có, tôi không thể giúp gì khác.


Cảm ơn liên kết đến mô-đun, nhưng tôi đã hy vọng thực hiện điều này với thư viện node.js tiêu chuẩn, sử dụng http.get ().
Vineet Kosaraju

0

Tôi đã gặp lỗi này khi đi từ môi trường phát triển sang môi trường sản xuất. Tôi bị ám ảnh với việc đưa https://vào tất cả các liên kết. Điều này là không cần thiết, vì vậy nó có thể là một giải pháp cho một số.


0

Tôi đã thoát khỏi http và thêm dấu gạch chéo (/). Tôi chỉ sử dụng 'node-test.herokuapp.com' này và nó đã hoạt động.


0

Nếu bạn vẫn phải đối mặt với việc kiểm tra cài đặt proxy, thì đối với tôi, đó là cài đặt proxy bị thiếu và không thể thực hiện yêu cầu vì http / https trực tiếp bị chặn. Vì vậy, tôi đã cấu hình proxy từ tổ chức của mình trong khi thực hiện yêu cầu.

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

Tôi đã giải quyết vấn đề này bằng cách xóa các ký tự không mong muốn khỏi mật khẩu cho kết nối. Ví dụ: tôi có các ký tự này: <##% và nó đã gây ra sự cố (rất có thể thẻ băm là nguyên nhân gốc rễ của vấn đề).


0

Hãy thử sử dụng địa chỉ IP của máy chủ thay vì tên máy chủ. Điều này làm việc cho tôi. Hy vọng nó sẽ làm việc cho bạn quá.


0

Vấn đề của tôi là chúng tôi đã phân tích cú pháp url và tạo http_options cho http.request ();

Tôi đang sử dụng request_url.host đã có số cổng với tên miền nên phải sử dụng 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;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.