Làm cách nào tôi có thể sử dụng proxy http với node.js http.Client?


137

Tôi muốn thực hiện một cuộc gọi HTTP gửi đi từ node.js, sử dụng tiêu chuẩn http.Client. Nhưng tôi không thể truy cập máy chủ từ xa trực tiếp từ mạng của mình và cần thông qua proxy.

Làm cách nào để tôi nói với node.js sử dụng proxy?


1
Tôi có cùng một vấn đề. Node.js đứng sau một tường lửa và tôi không thể tạo HTTPClient cho một trang web bên ngoài.
ddallala

Câu trả lời:


152

Câu trả lời của Tim Macfarlane rất gần với việc sử dụng proxy HTTP.

Sử dụng proxy HTTP (đối với các yêu cầu không bảo mật) rất đơn giản. Bạn kết nối với proxy và thực hiện yêu cầu bình thường ngoại trừ phần đường dẫn bao gồm url đầy đủ và tiêu đề máy chủ được đặt thành máy chủ bạn muốn kết nối.
Tim rất gần với câu trả lời của anh ấy nhưng anh ấy đã bỏ lỡ việc đặt tiêu đề máy chủ đúng cách.

var http = require("http");

var options = {
  host: "proxy",
  port: 8080,
  path: "http://www.google.com",
  headers: {
    Host: "www.google.com"
  }
};
http.get(options, function(res) {
  console.log(res);
  res.pipe(process.stdout);
});

Đối với bản ghi, câu trả lời của anh ta không hoạt động với http://nodejs.org/ nhưng đó là do máy chủ của họ không quan tâm đến tiêu đề máy chủ không chính xác.


1
Có cách nào để sử dụng http https kết nối cổng https không? dường như không có phương pháp dễ dàng
Gohan

@Gohan Xem câu trả lời của Chris bên dưới để biết ví dụ về cách kết nối với máy chủ https thông qua và http proxy.
HairOfTheDog

nếu bạn nhận được yêu cầu xấu, hãy đặt đường dẫn: '/'
Laurent Debricon

9
Làm cách nào tôi có thể tích hợp người dùng proxy và mật khẩu proxy trong khối tùy chọn?
Twistleton

Điều này đã thay đổi? Ngay cả với đích đến cuối cùng là một máy chủ cục bộ khác, tôi vẫn nhận được 404và máy chủ đích không bao giờ nhận được yêu cầu ..
OJFord

53

Bạn có thể sử dụng yêu cầu , tôi chỉ thấy nó dễ sử dụng proxy trên node.js, chỉ với một tham số "proxy" bên ngoài, thậm chí nhiều hơn nó còn hỗ trợ HTTPS thông qua proxy http.

var request = require('request');

request({
  'url':'https://anysite.you.want/sub/sub',
  'method': "GET",
  'proxy':'http://yourproxy:8087'
},function (error, response, body) {
  if (!error && response.statusCode == 200) {
    console.log(body);
  }
})

1
Làm việc cho cả hai httphttpstrong trường hợp của tôi, Cảm ơn rất nhiều
Samuel Bushi

bất kỳ ý tưởng tại sao điều này sẽ không làm việc cho các trang nội bộ?
keinabel

1
Tôi ngạc nhiên các trang nội bộ nằm phía sau một proxy. Bạn có chắc chắn rằng proxy không bị bỏ qua cho các trang nội bộ không? Có phải trên một vlan khác nhau?
Chanoch

Bạn cần chỉ định xác thực bằng cách nào đó (sẽ đăng nó ở đây nếu tôi tìm ra nó)
Igor L.

Tôi đã gặp lỗi này khi sử dụng yêu cầu với proxy: Lỗi: không thể thiết lập ổ cắm đường hầm, nguyên nhân = kết nối ECONNREFUSED 127.0.0.1:80
Federico Caccia

35

Một điều khiến tôi mất một thời gian để tìm ra, sử dụng 'http' để truy cập proxy, ngay cả khi bạn đang cố gắng ủy quyền qua máy chủ https. Điều này hoạt động với tôi bằng cách sử dụng Charles (phân tích giao thức osx):

var http = require('http');

http.get ({
    host: '127.0.0.1',
    port: 8888,
    path: 'https://www.google.com/accounts/OAuthGetRequestToken'
}, function (response) {
    console.log (response);
});

1
Mã ở trên không hoạt động với tôi và nó liên quan đến vấn đề github.com/joyent/node/issues/2474 kiểm tra câu trả lời của koichik, chúng tôi phải sử dụng "phương thức": "kết nối" và trên sự kiện "kết nối", chúng tôi đã gửi thông tin đường dẫn .
Palani

16

Như @Renat ở đây đã được đề cập, lưu lượng HTTP được ủy quyền xuất hiện trong các yêu cầu HTTP khá bình thường. Thực hiện yêu cầu đối với proxy, chuyển URL đầy đủ của đích đến dưới dạng đường dẫn.

var http = require ('http');

http.get ({
    host: 'my.proxy.com',
    port: 8080,
    path: 'http://nodejs.org/'
}, function (response) {
    console.log (response);
});

2
Điều này dường như hoạt động mặc dù Fiddler gọi đó là vi phạm giao thức, điều đó cho thấy đây không phải là một yêu cầu HTTP thông qua proxy phù hợp ...
Marc

11

Tôi nghĩ rằng tôi sẽ thêm mô-đun này mà tôi đã tìm thấy: https://www.npmjs.org/package/global-tunnel , hoạt động rất tốt cho tôi (Làm việc ngay lập tức với tất cả các mô-đun mã của tôi và bên thứ ba chỉ với mã bên dưới).

require('global-tunnel').initialize({
  host: '10.0.0.10',
  port: 8080
});

Thực hiện việc này một lần và tất cả http (và https) trong ứng dụng của bạn đều đi qua proxy.

Thay phiên, gọi

require('global-tunnel').initialize();

Sẽ sử dụng http_proxy biến môi trường


2
Điều này làm việc cho tôi! Thực tế theo cách này bạn tách rời proxy khỏi mã và sử dụng cấu hình hiện có cho npm! đó là con đường để đi tôi sẽ nói
Caesaregb

@NeelBasu Đúng vậy
Major-mann

9

Tôi đã mua máy chủ proxy riêng, sau khi mua tôi nhận được:

255.255.255.255 // IP address of proxy server
99999 // port of proxy server
username // authentication username of proxy server
password // authentication password of proxy server

Và tôi muốn sử dụng nó. Câu trả lời đầu tiêncâu trả lời thứ hai chỉ hoạt động cho http (proxy) -> http (đích), tuy nhiên tôi muốn http (proxy) -> https (đích).

Và đối với đích https, tốt hơn là sử dụng trực tiếp đường hầm HTTP . Tôi tìm thấy giải pháp ở đây . Mã cuối cùng:

const http = require('http')
const https = require('https')
const username = 'username'
const password = 'password'
const auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64')

http.request({
  host: '255.255.255.255', // IP address of proxy server
  port: 99999, // port of proxy server
  method: 'CONNECT',
  path: 'kinopoisk.ru:443', // some destination, add 443 port for https!
  headers: {
    'Proxy-Authorization': auth
  },
}).on('connect', (res, socket) => {
  if (res.statusCode === 200) { // connected to proxy server
    https.get({
      host: 'www.kinopoisk.ru',
      socket: socket,    // using a tunnel
      agent: false,      // cannot use a default agent
      path: '/your/url'  // specify path to get from server
    }, (res) => {
      let chunks = []
      res.on('data', chunk => chunks.push(chunk))
      res.on('end', () => {
        console.log('DONE', Buffer.concat(chunks).toString('utf8'))
      })
    })
  }
}).on('error', (err) => {
  console.error('error', err)
}).end()

7

Gói http 'yêu cầu' dường như có tính năng này:

https://github.com/mikeal/request

Ví dụ: đối tượng yêu cầu 'r' bên dưới sử dụng localproxy để truy cập các yêu cầu của nó:

var r = request.defaults({'proxy':'http://localproxy.com'})

http.createServer(function (req, resp) {
  if (req.url === '/doodle.png') {
    r.get('http://google.com/doodle.png').pipe(resp)
  }
})

Thật không may, không có mặc định "toàn cầu" để người dùng lib sử dụng điều này không thể sửa đổi proxy trừ khi lib chuyển qua các tùy chọn http ...

HTH, Chris


gói http yêu cầu giúp cho mã của bạn dễ dàng chuyển đổi giữa sử dụng proxy và không sử dụng proxy (điều này khá hữu ích trên máy tính xách tay của tôi).
Jon Madison

5

Về cơ bản, bạn không cần một hỗ trợ proxy rõ ràng. Giao thức proxy khá đơn giản và dựa trên giao thức HTTP thông thường. Bạn chỉ cần sử dụng máy chủ proxy và cổng khi kết nối với HTTPClient. Ví dụ (từ tài liệu của node.js):

var http = require('http');
var google = http.createClient(3128, 'your.proxy.host');
var request = google.request('GET', '/',
  {'host': 'www.google.com'});
request.end();
...

Vì vậy, về cơ bản, bạn kết nối với proxy của mình nhưng thực hiện một yêu cầu tới "http://www.google.com".


3
http.createClient không được dùng nữa, Tim Macfarlane đang sử dụng http.get mới hơn bên dưới
sami

1
Điều này dường như sẽ không còn hoạt động với node.js kể từ v5.6 vì chúng đã loại bỏ creatClient .
Marc

5

Trong trường hợp bạn cần sử dụng ủy quyền cơ bản cho nhà cung cấp proxy của mình, chỉ cần sử dụng như sau:

var http = require("http");

var options = {
    host:       FarmerAdapter.PROXY_HOST,
    port:       FarmerAdapter.PROXY_PORT,
    path:       requestedUrl,
    headers:    {
        'Proxy-Authorization':  'Basic ' + new Buffer(FarmerAdapter.PROXY_USER + ':' + FarmerAdapter.PROXY_PASS).toString('base64')
    }
};

var request = http.request(options, function(response) {
    var chunks = [];
    response.on('data', function(chunk) {
        chunks.push(chunk);
    });
    response.on('end', function() {
        console.log('Response', Buffer.concat(chunks).toString());
    });
});

request.on('error', function(error) {
    console.log(error.message);
});

request.end();

1
Tôi có thể tìm thấy "FarmerAd CHƯƠNG" ở đâu?
Alex

3

Nút nên hỗ trợ sử dụng biến môi trường http_proxy - vì vậy nó là nền tảng chéo và hoạt động trên các cài đặt hệ thống thay vì yêu cầu cấu hình trên mỗi ứng dụng.

Sử dụng các giải pháp được cung cấp, tôi muốn giới thiệu như sau:

Bản thảo

get_url = (url, response) ->
  if process.env.http_proxy?
    match = process.env.http_proxy.match /^(http:\/\/)?([^:\/]+)(:([0-9]+))?/i
    if match
      http.get { host: match[2], port: (if match[4]? then match[4] else 80), path: url }, response
      return
  http.get url, response

Javascript

get_url = function(url, response) {
  var match;
  if (process.env.http_proxy != null) {
    match = process.env.http_proxy.match(/^(http:\/\/)?([^:\/]+)(:([0-9]+))?/i);
    if (match) {
      http.get({
        host: match[2],
        port: (match[4] != null ? match[4] : 80),
        path: url
      }, response);
      return;
    }
  }
  return http.get(url, response);
};

Cách sử dụng Để sử dụng phương thức, chỉ cần thay thế http.get một cách hiệu quả, ví dụ như sau đây ghi trang chỉ mục của google vào một tệp có tên test.htm:

file = fs.createWriteStream path.resolve(__dirname, "test.htm")
get_url "http://www.google.com.au/", (response) ->
  response.pipe file
  response.on "end", ->
    console.log "complete"

Đặt http_proxy dường như không có bất kỳ ảnh hưởng nào khi chạy Node trên Windows.
EricLaw

Nó nên hoạt động trong Windows (đó là hệ thống chính tôi đang sử dụng). Đảm bảo sau khi bạn đã đặt cài đặt mà bạn đã đặt lại phiên cuối của mình (nếu được đặt qua bảng điều khiển và không được đặt). Bạn sẽ có thể kiểm tra nó được đặt chính xác bằng echo% HTTP_PROXY% Hoặc tốt hơn nữa là bạn nên sử dụng nút chính nút -e "console.log (process.env.http_proxy);" Điều này làm việc cho tôi dưới Windows, rất may mắn.
Lu-ca

1

Câu trả lời của Imskull gần như có tác dụng với tôi, nhưng tôi phải thực hiện một số thay đổi. Thay đổi thực sự duy nhất là thêm tên người dùng, mật khẩu và đặt từ chốiUnauthorized thành false. Tôi không thể bình luận vì vậy tôi đưa ra câu trả lời.

Nếu bạn chạy mã, nó sẽ giúp bạn có được tiêu đề của những câu chuyện hiện tại trên Hacker News, theo hướng dẫn này: http://smalljs.org/package-manager/npm/

var cheerio = require('cheerio');
var request = require('request');

request({
    'url': 'https://news.ycombinator.com/',
    'proxy': 'http://Username:Password@YourProxy:Port/',
    'rejectUnauthorized': false
}, function(error, response, body) {
    if (!error && response.statusCode == 200) {
        if (response.body) {
            var $ = cheerio.load(response.body);
            $('td.title a').each(function() {
                console.log($(this).text());
            });
       }
    } else {
        console.log('Error or status not equal 200.');
    }
});

1

Tôi nghĩ rằng có một sự thay thế tốt hơn cho các câu trả lời vào năm 2019. Chúng ta có thể sử dụng global-tunnel-nggói để khởi tạo proxy và không gây ô nhiễm httphoặc httpsmã dựa trên mọi nơi. Vì vậy, global-tunnel-nggói cài đặt đầu tiên :

npm install global-tunnel-ng

Sau đó thay đổi triển khai của bạn để khởi tạo proxy nếu cần là:

const globalTunnel = require('global-tunnel-ng');

globalTunnel.initialize({
  host: 'proxy.host.name.or.ip',
  port: 8080
});


0

http://groups.google.com/group/nodejs/browse_thread/thread/d5aadbcaa00c3f7/12ebf01d7ec415c3?lnk=gst&q=proxy#12ebf01d7ec415c3

Dựa trên câu trả lời từ chủ đề này nó sẽ có vẻ như bạn có thể sử dụng proxychains để chạy Node.js thông qua máy chủ proxy:
$ proxychains /path/to/node application.js

Cá nhân tôi không thể cài đặt bất kỳ phiên bản proxy nào trên Cygwin / Windows môi trường nên không thể kiểm tra nó.

Hơn nữa, họ cũng nói về việc sử dụng kết nối proxy nhưng tôi không thể tìm thấy bất kỳ tài liệu nào về cách thực hiện việc này.

Nói tóm lại, tôi vẫn bị mắc kẹt, nhưng có lẽ ai đó có thể sử dụng thông tin này để tìm một công việc phù hợp.


cập nhật: sau khi một số điều tra phát hiện ra rằng tôi không thể xây dựng proxy trên CygWin vì RTLD_NEXT không được hỗ trợ.
ddallala


0

sử dụng 'https-proxy-agent' như thế này

var HttpsProxyAgent = require('https-proxy-agent');
var proxy = process.env.https_proxy || 'other proxy address';
var agent = new HttpsProxyAgent(proxy);

options = {
    //...
    agent : agent
}

https.get(options, (res)=>{...});

0

Nếu bạn có sơ đồ xác thực http cơ bản, bạn phải tạo một chuỗi base64 myuser:mypasswordvà sau đó thêm "Cơ bản" vào đầu. Đó là giá trị của tiêu đề Ủy quyền Proxy , đây là một ví dụ:

var Http = require('http');

var req = Http.request({
    host: 'myproxy.com.zx',
    port: 8080,
    headers:{"Proxy-Authorization": "Basic bXl1c2VyOm15cGFzc3dvcmQ="},
    method: 'GET',
    path: 'http://www.google.com/'
    }, function (res) {
        res.on('data', function (data) {
        console.log(data.toString());
    });
});

req.end();

Trong nodejs bạn có thể sử dụng Bộ đệm để mã hóa

var encodedData = Buffer.from('myuser:mypassword').toString('base64');

console.log(encodedData);

Ví dụ, trong các trình duyệt, bạn có thể mã hóa trong base64 bằng btoa () , hữu ích trong các yêu cầu ajax trong trình duyệt mà không cần cài đặt proxy thực hiện yêu cầu bằng proxy.

var encodedData = btoa('myuser:mypassword')

console.log(encodedData);

Làm thế nào để tìm chương trình wich chấp nhận máy chủ proxy?

Nếu chúng tôi không có DNS tùy chỉnh được định cấu hình (sẽ ném một cái gì đó như ERR_NAME_NOT_RESOLVED), khi chúng tôi thực hiện một yêu cầu, phản hồi (mã 407) sẽ thông báo trong tiêu đề phản hồi mà chương trình xác thực http mà proxy đang sử dụng.

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.