Bagaimana cara menggunakan proxy http dengan node.js http.Client?


143

Saya ingin membuat panggilan HTTP keluar dari node.js, menggunakan standar http.Client. Tetapi saya tidak dapat menjangkau server jarak jauh secara langsung dari jaringan saya dan perlu melalui proxy.

Bagaimana cara memberi tahu node.js untuk menggunakan proxy?


1
Saya mengalami masalah yang sama. Node.js berada di belakang firewall dan saya tidak dapat membuat HTTPClient ke situs web eksternal.
ddallala

Jawaban:


156

Tim Macfarlane 's jawaban dekat dengan salam untuk menggunakan proxy HTTP.

Menggunakan proxy HTTP (untuk permintaan yang tidak aman) sangat sederhana. Anda terhubung ke proxy dan membuat permintaan secara normal kecuali bagian jalur menyertakan url lengkap dan header host disetel ke host yang ingin Anda sambungkan.
Tim sangat dekat dengan jawabannya tetapi dia gagal mengatur sundulan tuan rumah dengan benar.

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

Sebagai catatan jawabannya berfungsi dengan http://nodejs.org/ tetapi itu karena server mereka tidak peduli header host salah.


1
Apakah ada cara untuk menggunakan http proxy menghubungkan port https? tampaknya tidak memiliki metode yang mudah
Gohan

@Gohan Lihat jawaban Chris di bawah ini untuk contoh tentang cara menyambung ke server https melalui dan proxy http.
HairOfTheDog

jika Anda mendapatkan permintaan yang buruk, letakkan jalur: '/'
Laurent Debricon

9
Bagaimana saya bisa mengintegrasikan proxy-user dan proxy-password di blok opsi?
Twistleton

Apakah ini berubah? Bahkan dengan tujuan akhir sebagai server lokal lain, saya mendapatkan a 404, dan server tujuan tidak pernah menerima permintaan tersebut ..
OJFord

57

Anda dapat menggunakan permintaan , saya baru saja menemukan bahwa sangat mudah menggunakan proxy pada node.js, hanya dengan satu parameter "proxy" eksternal, bahkan lebih mendukung HTTPS melalui 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
Bekerja untuk keduanya httpdan httpsdalam kasus saya, Terima kasih banyak
Samuel Bushi

ada ide mengapa ini tidak akan berfungsi untuk halaman perusahaan internal?
keinabel

1
Saya terkejut halaman perusahaan internal berada di belakang proxy. Apakah Anda yakin bahwa proxy tidak sedang dilewati untuk halaman internal? Apakah di vlan yang berbeda?
Chanoch

Anda perlu menentukan otentikasi entah bagaimana (akan mempostingnya di sini jika saya mengetahuinya)
Igor L.

1
@IgorL. Saya membuatnya berfungsi dengan Auth dan Modul Permintaan, denganheaders: {'Proxy-Authorization': XXXX}
Aaron McKeehan

36

Satu hal yang butuh waktu lama bagi saya untuk mengetahuinya, gunakan 'http' untuk mengakses proxy, bahkan jika Anda mencoba proxy melalui ke server https. Ini berfungsi untuk saya menggunakan Charles (osx protocol analyzer):

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
Kode di atas tidak berfungsi untuk saya, dan terkait dengan masalah github.com/joyent/node/issues/2474 periksa jawaban koichik kita harus menggunakan "metode": "terhubung" dan pada acara "sambungkan", kami telah mengirim informasi jalur .
Palani

16

Seperti yang telah disebutkan @Renat di sini, lalu lintas HTTP yang diproksikan masuk dalam permintaan HTTP yang cukup normal. Buat permintaan terhadap proxy, dengan meneruskan URL lengkap tujuan sebagai jalur.

var http = require ('http');

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

2
Ini tampaknya berfungsi meskipun Fiddler menyebutnya sebagai pelanggaran protokol yang menunjukkan itu bukan permintaan HTTP melalui proxy yang tepat ...
Marc

12

Saya membeli server proxy pribadi, setelah pembelian saya mendapat:

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

Dan saya ingin menggunakannya. Jawaban pertama dan jawaban kedua hanya berfungsi untuk http (proxy) -> http (tujuan), namun saya ingin http (proxy) -> https (tujuan).

Dan untuk tujuan https akan lebih baik menggunakan HTTP tunnel secara langsung. Saya menemukan solusi di sini . Kode terakhir:

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

Ini berhasil untuk saya! Terima kasih banyak! 😄
Tai JinYuan

11

Pikir saya akan menambahkan modul ini saya menemukan: https://www.npmjs.org/package/global-tunnel , yang bekerja sangat baik untuk saya (Bekerja langsung dengan semua kode saya dan modul pihak ketiga hanya dengan kode di bawah).

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

Lakukan ini sekali, dan semua http (dan https) di aplikasi Anda melewati proxy.

Bergantian, menelepon

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

Akan menggunakan http_proxyvariabel lingkungan


2
Ini berhasil untuk saya! Sebenarnya dengan cara ini Anda memisahkan proxy dari kode dan menggunakan konfigurasi yang ada untuk npm! itulah cara untuk pergi, saya akan mengatakan
cesaregb

@NeelBasu Ya benar
mayor-mann

7

Paket http 'request' tampaknya memiliki fitur ini:

https://github.com/mikeal/request

Misalnya, objek permintaan 'r' di bawah ini menggunakan proxy lokal untuk mengakses permintaannya:

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

Sayangnya tidak ada default "global" sehingga pengguna lib yang menggunakan ini tidak dapat mengubah proxy kecuali lib melewati opsi http ...

HTH, Chris


paket http permintaan mempermudah untuk mengizinkan kode Anda beralih antara penggunaan proxy dan non proxy (yang cukup berguna di laptop saya).
Jon Madison

5

Pada dasarnya Anda tidak memerlukan dukungan proxy eksplisit. Protokol proxy cukup sederhana dan berdasarkan pada protokol HTTP biasa. Anda hanya perlu menggunakan host dan port proxy Anda saat menghubungkan dengan HTTPClient. Contoh (dari dokumen 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();
...

Jadi pada dasarnya Anda terhubung ke proxy Anda tetapi melakukan permintaan ke "http://www.google.com".


3
http.createClient tidak digunakan lagi, Tim Macfarlane menggunakan http.get di bawah ini
sami

1
Ini tampaknya tidak akan lagi berfungsi dengan node.js pada v5.6 karena mereka telah menghapus createClient .
Marc

5

Jika Anda perlu menggunakan otorisasi dasar untuk penyedia proxy Anda, cukup gunakan yang berikut ini:

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
di mana saya bisa menemukan "FarmerAdapter"?
Manjeet

3

Node harus mendukung penggunaan variabel lingkungan http_proxy - jadi ini lintas platform dan berfungsi pada pengaturan sistem daripada memerlukan konfigurasi per aplikasi.

Menggunakan solusi yang disediakan, saya akan merekomendasikan yang berikut ini:

Coffeescript

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

Penggunaan Untuk menggunakan metode ini, secara efektif cukup ganti http.get, misalnya berikut ini menulis halaman indeks google ke file bernama 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"

Pengaturan http_proxy tampaknya tidak berpengaruh apa pun saat menjalankan Node di Windows.
EricLaw

Ini harus bekerja di bawah Windows (itu adalah sistem utama yang saya gunakan). Pastikan setelah Anda mengatur pengaturan bahwa Anda telah mengatur ulang sesi terminal Anda (jika diatur melalui panel kontrol dan tidak diatur). Anda harus dapat memeriksa apakah itu disetel dengan benar menggunakan echo% HTTP_PROXY% Atau bahkan lebih baik Anda harus menggunakan simpul itu sendiri node -e "console.log (process.env.http_proxy);" Ini bekerja untuk saya di bawah Windows, semoga berhasil.
Lukas

1

Jawaban Imskull hampir berhasil bagi saya, tetapi saya harus membuat beberapa perubahan. Satu-satunya perubahan nyata adalah menambahkan nama pengguna, kata sandi, dan pengaturan rejectUnauthorized menjadi false. Saya tidak bisa berkomentar jadi saya tulis ini sebagai jawaban.

Jika Anda menjalankan kodenya, Anda akan mendapatkan judul dari cerita terkini di Hacker News, sesuai tutorial ini: http://smalljs.org/package-managers/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

Saya pikir ada alternatif yang lebih baik untuk jawaban pada 2019. Kita dapat menggunakan global-tunnel-ngpaket untuk menginisialisasi proxy dan tidak mencemari httpatau httpsberdasarkan kode di mana-mana. Jadi global-tunnel-ngpaket instal pertama :

npm install global-tunnel-ng

Kemudian ubah implementasi Anda untuk menginisialisasi proxy jika diperlukan sebagai:

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

Berdasarkan jawaban dari utas ini, sepertinya Anda dapat menggunakan proxychains untuk menjalankan node.js melalui server proxy:
$ proxychains /path/to/node application.js

Secara pribadi saya tidak dapat menginstal salah satu versi proxychains di Cygwin / Windows lingkungan sehingga tidak dapat mengujinya.

Selain itu, mereka juga berbicara tentang penggunaan koneksi-proxy tetapi saya tidak dapat menemukan dokumentasi apa pun tentang cara melakukan ini.

Singkatnya, saya masih buntu, tetapi mungkin seseorang dapat menggunakan info ini untuk menemukan solusi yang cocok.


update: setelah beberapa penyelidikan menemukan bahwa saya tidak dapat membangun proxychains di CygWin karena RTLD_NEXT tidak didukung.
ddallala


0

gunakan 'https-proxy-agent' seperti ini

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

Jika Anda memiliki skema otentikasi http Dasar, Anda harus membuat string base64 myuser:mypassword, dan kemudian menambahkan "Dasar" di awal. Itulah nilai dari Proxy-Authorization header, berikut contohnya:

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

Di nodejs Anda bisa menggunakan Buffer untuk menyandikan

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

console.log(encodedData);

Seperti contoh, di browser Anda dapat menyandikan dalam base64 menggunakan btoa () , berguna dalam permintaan ajax di browser tanpa pengaturan proxy yang melakukan permintaan menggunakan proxy.

var encodedData = btoa('myuser:mypassword')

console.log(encodedData);

Bagaimana menemukan skema mana yang menerima server proxy?

Jika kita tidak memiliki DNS khusus yang dikonfigurasi (itu akan memunculkan sesuatu seperti ERR_NAME_NOT_RESOLVED), saat kita melakukan permintaan, tanggapan (kode 407) harus menginformasikan di header tanggapan skema otentikasi http mana yang digunakan proxy.


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.