Bir http proxy'yi node.js http.Client ile nasıl kullanabilirim?


137

Standardı kullanarak node.js'den giden HTTP çağrısı yapmak istiyorum http.Client. Ancak uzak sunucuya doğrudan ağımdan erişemiyorum ve bir proxy'den geçmem gerekiyor.

Node.js'ye proxy'yi nasıl kullanmasını nasıl söyleyebilirim?


1
Aynı sorunu yaşıyorum. Node.js bir güvenlik duvarının arkasında ve harici bir web sitesine HTTPClient oluşturamıyorum.
ddallala

Yanıtlar:


153

Tim Macfarlane 'ın cevabı HTTP proxy kullanarak getirmedi yakındı.

HTTP proxy (güvenli olmayan istekler için) kullanmak çok basittir. Proxy'ye bağlanır ve yol kısmının tam URL'yi içermesi ve ana bilgisayar üstbilgisinin bağlanmak istediğiniz ana bilgisayara ayarlanması dışında isteği normal şekilde yaparsınız.
Tim cevabına çok yakındı ama ana bilgisayar başlığını düzgün bir şekilde ayarlamayı kaçırdı.

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

Kayıt için cevabı http://nodejs.org/ ile çalışır, ancak sunucularının ana bilgisayar üstbilgisinin yanlış olduğunu umursamamasıdır.


1
Http proxy bağlantı https bağlantı noktasını kullanmanın bir yolu var mı? kolay bir yöntemi yok gibi görünüyor
Gohan

@ Gohan Bir https sunucusuna ve http proxy üzerinden nasıl bağlanacağına ilişkin bir örnek için aşağıdaki Chris'in cevabına bakın.
HairOfTheDog

Kötü bir istek alırsanız, yolu
belirtin

9
Proxy-kullanıcı ve proxy-parolayı seçenekler bloğuna nasıl entegre edebilirim?
Twistleton

Bu değişti mi? Hatta başka bir yerel sunucu olarak son hedef ile, bir olsun 404ve hedef sunucu asla isteği almaz ..
OJFord

53

Sen kullanabilirsiniz isteği Sadece tek bir dış "vekil" parametresi ile, daha da bir http proxy üzerinden HTTPS destekler node.js üzerinde kullanım proxy inanılmaz kolay bulundu.

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
Her ikisi için de çalıştı httpve httpsteşekkür, benim durumumda çok
Samuel Bushi

bunun dahili şirket sayfaları için neden işe yaramayacağına dair bir fikriniz var mı?
keinabel

1
İç corp sayfalarının bir vekilin arkasında olduğuna şaşırdım. Dahili sayfalar için proxy'nin atlanmadığından emin misiniz? Farklı bir vlanda mı?
Chanoch

Kimlik doğrulamayı bir şekilde belirtmeniz gerekiyor (eğer
Igor L.

Proxy ile istek kullanarak bu hatayı aldım: Hata: tünel soketi kurulamadı, neden = ECONNREFUSED bağlayın 127.0.0.1:80
Federico Caccia

35

Anlamak için biraz zamanımı alan bir şey, bir https sunucusuna proxy yapmaya çalışsanız bile proxy'ye erişmek için 'http' kullanın. Charles (osx protokol analizörü) kullanarak bu benim için çalışıyor:

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
Yukarıdaki kod benim için çalışmıyor ve onun sorunu ile ilgili github.com/joyent/node/issues/2474 koichik'in cevabını kontrol etmeliyiz "method": "connect" ve "connect" olayında yol bilgilerini göndermeliyiz .
Palani

16

@Renat burada daha önce de belirtildiği gibi, proxy HTTP trafiği oldukça normal HTTP isteklerinde gelir. Hedefin tam URL'sini yol olarak ileterek proxy'ye karşı istekte bulunun.

var http = require ('http');

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

2
Fiddler buna, proxy üzerinden uygun bir HTTP isteği olmadığını gösteren bir protokol ihlali diyor olsa da işe yarıyor ...
Marc

11

Ben buldum bu modülü eklemek düşündüm: https://www.npmjs.org/package/global-tunnel , benim için harika çalıştı (hemen hemen tüm kod ile tüm kodum ve üçüncü taraf modülleri ile hemen çalıştı).

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

Bunu bir kez yapın ve uygulamanızdaki tüm http (ve https) proxy üzerinden geçer.

Alternatif olarak,

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

Kullanacak mı http_proxyortam değişkeni


2
Bu benim için çalıştı! Aslında bu şekilde proxy'yi koddan ayırır ve npm için mevcut yapılandırmayı kullanırsınız! diyebilirim ki
cesaregb

@NeelBasu Evet öyle
major-mann

10

Özel proxy sunucusu satın aldım, satın aldıktan sonra:

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

Ve kullanmak istedim. İlk cevap ve ikinci cevap sadece http (proxy) -> http (hedef) için çalıştı, ancak http (proxy) -> https (hedef) istedim.

Ve https hedefi için HTTP tünelini doğrudan kullanmak daha iyi olur . Burada çözüm buldum . Son kod:

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

'Request' http paketi şu özelliğe sahip gibi görünüyor:

https://github.com/mikeal/request

Örneğin, aşağıdaki 'r' istek nesnesi isteklerine erişmek için localproxy kullanır:

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

Ne yazık ki "global" varsayılanları yoktur, bu yüzden lib kullanan http kullanıcıları geçmediği sürece bunu kullanan kütüphanelerin kullanıcıları proxy'yi değiştiremez ...

HTH, Chris


istek http paketi, kodunuzun proxy ve proxy olmayan kullanım arasında geçiş yapmasına izin vermeyi kolaylaştırır (dizüstü bilgisayarımda oldukça kullanışlıdır).
Jon Madison

5

Temel olarak açık bir proxy desteğine ihtiyacınız yoktur. Proxy protokolü oldukça basittir ve normal HTTP protokolünü temel alır. HTTPClient ile bağlantı kurarken proxy ana makinenizi ve bağlantı noktanızı kullanmanız yeterlidir. Örnek (node.js belgelerinden):

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

Temel olarak proxy'nize bağlanırsınız ancak "http://www.google.com" adresine bir istekte bulunursunuz.


3
http.createClient kullanımdan kaldırıldı, Tim Macfarlane daha yeni http.get'i kullanıyor
sami

1
Bu, createClient'i kaldırdıkları için artık v5.6'dan beri node.js ile çalışmaz .
Marc

5

Proxy sağlayıcınız için temel yetkilendirmeyi kullanmanız gerekirse, aşağıdakileri kullanmanız yeterlidir:

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
"FarmerAdapter" nerede bulabilirim?
Alex

3

Düğüm http_proxy ortam değişkenini kullanmayı desteklemelidir - bu nedenle çapraz platformdur ve uygulama başına yapılandırma gerektirmek yerine sistem ayarlarında çalışır.

Sağlanan çözümleri kullanarak aşağıdakileri tavsiye ederim:

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

Kullanım Yöntemi kullanmak için, http.get'i etkili bir şekilde değiştirin; örneğin, google dizin sayfasını test.htm adlı bir dosyaya yazar:

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"

Http_proxy ayarının Windows üzerinde Düğüm çalıştırılırken herhangi bir etkisi olmadığı görülüyor.
EricLaw

Windows altında çalışmalıdır (kullandığım birincil sistemdir). Terminal oturumunuzu sıfırladığınız ayarı yaptıktan sonra (kontrol panelinden ayarlanmışsa ve ayarlanmamışsa) emin olun. Echo% HTTP_PROXY% kullanarak doğru ayarlandığını kontrol edebilmelisiniz. Daha da iyisi, düğümün kendisini node -e "console.log (process.env.http_proxy);" Bu benim için Windows altında çalıştı, çok iyi şanslar.
Luke

1

Imskull'un yanıtı neredeyse benim için çalıştı, ama bazı değişiklikler yapmak zorunda kaldım. Tek gerçek değişiklik kullanıcı adı, şifre eklemek ve rejectUnauthorized değerini false olarak ayarlamaktır. Yorum yapamadım, bu yüzden bir cevap verdim.

Kodu çalıştırırsanız, bu eğiticiye göre Hacker News'deki mevcut hikayelerin başlıklarını alacaksınız: 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

2019'dan itibaren cevaplara daha iyi bir alternatif olduğunu düşünüyorum. global-tunnel-ngPaketi proxy'yi başlatmak ve her yerde httpveya httpstabanlı kodu kirletmemek için kullanabiliriz . Yani ilk yükleme global-tunnel-ngpaketi:

npm install global-tunnel-ng

Ardından, gerekirse proxy'yi başlatmak için uygulamalarınızı şu şekilde değiştirin:

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

Bu iş parçacığının yanıtlarına göre, node.js'yi proxy sunucusu üzerinden çalıştırmak için proxychains kullanabileceğiniz anlaşılıyor :
$ proxychains /path/to/node application.js

Şahsen Cygwin / Windows ortamına proxychains sürümlerinden herhangi birini yükleyemedim, bu yüzden test edemedim.

Ayrıca, connect-proxy kullanımı hakkında da konuştular, ancak bunun nasıl yapılacağı hakkında herhangi bir belge bulamadım.

Kısacası, hala takılı kalıyorum, ama belki birisi bu bilgiyi uygun bir çözüm bulmak için kullanabilir.


update: bazı araştırmalar RTLD_NEXT desteklenmediği için CygWin üzerinde proxy zincirleri oluşturamadığımı öğrendikten sonra.
ddallala


0

bunun gibi 'https-proxy-agent'ı kullan

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

Eğer varsa Temel http kimlik doğrulama şeması Eğer bir base64 dize yapmak zorunda myuser:mypasswordve sonra başlangıçta "Basic" ekleyin. Proxy-Authorization üstbilgisinin değeri budur , burada bir örnek:

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

Nodejs size kullanabilirsiniz Tampon encode

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

console.log(encodedData);

Örneğin tarayıcılarda, proxy kullanarak bir istek gerçekleştiren proxy ayarları olmayan bir tarayıcıdaki ajax isteklerinde yararlı olan btoa () kullanarak base64 içinde kodlayabilirsiniz .

var encodedData = btoa('myuser:mypassword')

console.log(encodedData);

Proxy sunucuyu kabul eden şema nasıl bulunur?

Yapılandırılmış özel bir DNS'imiz yoksa (bu ERR_NAME_NOT_RESOLVED gibi bir şey atacak), bir istekte bulunduğumuzda yanıt (kod 407) yanıt başlıklarında proxy'nin hangi http kimlik doğrulama şemasını kullandığını bildirmelidir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.