node.js http.Clientでhttpプロキシを使用するにはどうすればよいですか?


137

標準を使用して、node.jsから発信HTTP呼び出しを行いたいhttp.Client。しかし、ネットワークから直接リモートサーバーにアクセスできず、プロキシを経由する必要があります。

node.jsにプロキシを使用するように指示するにはどうすればよいですか?


1
同じ問題が発生しています。Node.jsがファイアウォールの背後にあり、外部WebサイトへのHTTPClientを作成できません。
ddallala

回答:


152

Tim Macfarlane回答は、HTTPプロキシの使用に関しては近いものでした。

HTTPプロキシの使用(安全でない要求の場合)は非常に簡単です。パス部分に完全なURLが含まれ、ホストヘッダーが接続先のホストに設定されていることを除いて、プロキシに接続してリクエストを通常どおり作成します。
ティムは彼の答えに非常に近かったが、ホストヘッダーを適切に設定できなかった。

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

記録のために、彼の答えはhttp://nodejs.org/で動作しますが、それは彼らのサーバーがホストヘッダーが正しくないことを気にしていないためです。


1
httpプロキシ接続httpsポートを使用する方法はありますか?簡単な方法はないようです
Gohan

@Gohan httpプロキシ経由でhttpsサーバーに接続する方法の例については、以下のChrisの回答を参照してください。
HairOfTheDog

不正なリクエストを
受け取った

9
オプションブロックにプロキシユーザーとプロキシパスワードを統合するにはどうすればよいですか?
Twistleton 2014

これは変わりましたか?でも、別のローカルサーバとしての最終目的地で、私が得る404..と送信先サーバがリクエストを受信することはありません
OJFord

53

requestを使用できます。1つの外部「proxy」パラメーターを使用するだけで、node.jsでプロキシを使用するのは信じられないほど簡単であることがわかりました。さらに、httpプロキシを介してHTTPSをサポートしています。

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
両方のために働いたhttphttps私の場合には、どうもありがとうございました
サミュエル・武士

これが社内の社内ページで機能しない理由はありますか?
ケイナベル2015

1
内部の企業ページがプロキシの背後にあることに驚いています。内部ページでプロキシがバイパスされていないと確信していますか?別のVLANにありますか?
Chanoch 2015

Uはどういうわけか認証を指定する必要があります(わかったらここに投稿します)
Igor L.

プロキシを使用したリクエストでこのエラーが発生しました:エラー:トンネリングソケットを確立できませんでした。原因=接続ECONNREFUSED 127.0.0.1:80
フェデリコ

35

私が理解するのにしばらく時間がかかった1つのことは、httpsサーバーにプロキシしようとしている場合でも、「http」を使用してプロキシにアクセスすることです。これはチャールズ(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
上記のコードは私のために機能していません、そしてそれは問題github.com/joyent/node/issues/2474に関連していますkoichikの答えを確認してください "method": "connect"を使用する必要があり、 "connect"イベントでパス情報を送信しています。
パラニ2014

16

ここで@Renatがすでに述べたように、プロキシされたHTTPトラフィックはかなり通常のHTTPリクエストで受信されます。宛先の完全なURLをパスとして渡して、プロキシに対してリクエストを行います。

var http = require ('http');

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

2
Fiddlerはこれをプロトコル違反と呼んでいますが、これは適切なHTTP要求経由プロキシではないことを示唆していますが、これは機能するようです...
Marc

11

:私は私が見つけたこのモジュールを追加するだろうと思ったhttps://www.npmjs.org/package/global-tunnel(コードのみ以下にすべての私のコードやサードパーティのモジュールですぐに働いた)、私のために素晴らしい仕事。

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

これを1回実行すると、アプリケーション内のすべてのhttp(およびhttps)がプロキシを通過します。

あるいは、呼び出し

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

http_proxy環境変数を使用します


2
これは私のために働いた!実際には、この方法でプロキシをコードから切り離し、npmの既存の構成を使用します。それは私が言うべき道です
cesaregb

@NeelBasuはい、そうです
メジャー

9

プライベートプロキシサーバーを購入しました。購入後、次のものが得られました。

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

そしてそれを使いたかった。最初の回答2番目の回答はhttp(proxy)-> http(destination)でのみ機能しましたが、http(proxy)-> https(destination)が必要でした。

また、https宛先の場合は、HTTPトンネルを直接使用することをお勧めします。私はここで解決策を見つけまし。最終コード:

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

「リクエスト」httpパッケージにはこの機能があるようです:

https://github.com/mikeal/request

たとえば、以下の 'r'リクエストオブジェクトはlocalproxyを使用してリクエストにアクセスします。

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

残念ながら、「グローバル」デフォルトはないため、これを使用するlibのユーザーは、libがhttpオプションを通過しない限り、プロキシを修正できません...

HTH、クリス


request httpパッケージを使用すると、コードでプロキシの使用と非プロキシの使用を簡単に切り替えることができます(これは私のラップトップで非常に便利です)。
Jon Madison、

5

基本的に、明示的なプロキシサポートは必要ありません。プロキシプロトコルはかなり単純で、通常のHTTPプロトコルに基づいています。HTTPClientに接続するときは、プロキシホストとポートを使用するだけです。例(node.js docsから):

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

したがって、基本的にはプロキシに接続しますが、「http://www.google.com」へのリクエストを行います。


3
http.createClientは廃止され、Tim Macfarlaneは以下の新しいhttp.getを使用しています
sami

1
createClientが削除されたため、v5.6以降、これはnode.jsでは動作しないようです。
マルク・

5

プロキシプロバイダーに基本認証を使用する必要がある場合は、次のコードを使用してください。

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」はどこにありますか?
Alex

3

ノードはhttp_proxy環境変数の使用をサポートする必要があります-したがって、それはクロスプラットフォームであり、アプリケーションごとの構成を必要とせずにシステム設定で動作します。

提供されたソリューションを使用して、私は以下をお勧めします:

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

使い方 このメソッドを使用するには、http.getを効果的に置き換えるだけです。たとえば、次のコードでは、googleのインデックスページを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"

WindowsでNodeを実行している場合、http_proxyを設定しても効果がないようです。
EricLaw、2014年

Windows(つまり、私が使用している主要なシステム)で動作するはずです。設定を行った後、ターミナルセッションをリセットしたことを確認してください(コントロールパネルで設定され、設定されていない場合)。echo%HTTP_PROXY%を使用して、正しく設定されていることを確認できるはずです。さらに良いのは、ノード自体を使用することですnode -e "console.log(process.env.http_proxy);" これはWindowsでうまくいきました。
ルーク

1

イムスカルの答えはほとんど私にとってはうまくいったが、私はいくつかの変更をしなければならなかった。実際の唯一の変更は、ユーザー名、パスワードの追加、およびrejectUnauthorizedの設定をfalseにすることです。コメントできなかったので答えました。

コードを実行すると、次のチュートリアルに従って、Hacker Newsの現在の記事のタイトルが表示されます。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年の時点で、回答に対するより良い代替案があると思います。このglobal-tunnel-ngパッケージを使用してプロキシを初期化し、どこでも、httpまたはhttpsベースのコードを汚染することはできません。したがって、最初にglobal-tunnel-ngパッケージをインストールします。

npm install global-tunnel-ng

次に、必要に応じてプロキシを初期化するように実装を変更します。

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

このスレッドからの回答に基づい て、プロキシチェーンを使用してプロキシサーバー経由でnode.jsを実行できるように思われます。
$ proxychains /path/to/node application.js

個人的には、Cygwin / Windows環境にプロキシチェーンバージョンをインストールできなかったため、テストできませんでした。

さらに、彼らはまた、connect-proxyの使用について話しましたが、これを行う方法に関するドキュメントは見つかりませんでした。

要するに、私はまだ行き詰まっていますが、おそらく誰かがこの情報を使用して適切な回避策を見つけることができます。


更新:調査の結果、RTLD_NEXTがサポートされていないため、CygWinでプロキシチェーンを構築できないことがわかりました。
ddallala


0

このように「https-proxy-agent」を使用します

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

あなたが持っている場合は基本 HTTP認証スキームを、あなたはのbase64文字列を作成する必要がありmyuser:mypassword、その後、初めに「基本」を追加します。これがProxy-Authorizationヘッダーの値です。ここでは例を示します。

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では、バッファを使用してエンコードできます

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

console.log(encodedData);

例と同様に、ブラウザーではbtoa()を使用してbase64でエンコードできます。これは、プロキシーを使用してリクエストを実行するプロキシー設定なしのブラウザーでのajaxリクエストに役立ちます。

var encodedData = btoa('myuser:mypassword')

console.log(encodedData);

スキームを見つける方法は、プロキシサーバーを受け入れますか?

カスタムDNSが構成されていない場合(ERR_NAME_NOT_RESOLVEDのようなものをスローします)、リクエストを実行すると、応答(コード407)は、プロキシが使用しているhttp認証スキームを応答ヘッダーで通知する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.