如何在 node.js http.Client 中使用 http 代理?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3862813/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 13:41:48  来源:igfitidea点击:

How can I use an http proxy with node.js http.Client?

httpproxynode.js

提问by Christian Berg

I want to make an outgoing HTTP call from node.js, using the standard http.Client. But I cannot reach the remote server directly from my network and need to go through a proxy.

我想从 node.js 进行传出 HTTP 调用,使用标准http.Client. 但是我无法直接从我的网络访问远程服务器,需要通过代理。

How do I tell node.js to use the proxy?

我如何告诉 node.js 使用代理?

回答by Samuel

Tim Macfarlane's answerwas close with regards to using a HTTP proxy.

关于使用 HTTP 代理,Tim Macfarlane回答很接近。

Using a HTTP proxy (for non secure requests) is very simple. You connect to the proxy and make the request normally except that the path part includes the full url and the host header is set to the host you want to connect to.
Tim was very close with his answer but he missed setting the host header properly.

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

For the record his answer does work with http://nodejs.org/but that's because their server doesn't care the host header is incorrect.

作为记录,他的回答确实适用于http://nodejs.org/,但那是因为他们的服务器不在乎主机标头是否不正确。

回答by Imskull

You can use request, I just found it's unbelievably easy to use proxy on node.js, just with one external "proxy" parameter, even more it supports HTTPS through a http proxy.

您可以使用request,我刚刚发现在 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);
  }
})

回答by Chris

One thing that took me a while to figure out, use 'http' to access the proxy, even if you're trying to proxy through to a https server. This works for me using Charles (osx protocol analyser):

我花了一段时间才弄清楚的一件事是,使用“http”访问代理,即使您尝试代理到 https 服务器。这对我使用 Charles(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);
});

回答by Tim Macfarlane

As @Renat here already mentioned, proxied HTTP traffic comes in pretty normal HTTP requests. Make the request against the proxy, passing the full URLof the destination as the path.

正如这里的@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);
});

回答by major-mann

Thought I would add this module I found: https://www.npmjs.org/package/global-tunnel, which worked great for me (Worked immediately with all my code and third party modules with only the code below).

以为我会添加我发现的这个模块:https://www.npmjs.org/package/global-tunnel,它对我很有用(立即使用我的所有代码和第三方模块,只有下面的代码)。

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

Do this once, and all http (and https) in your application goes through the proxy.

执行一次,应用程序中的所有 http(和 https)都会通过代理。

Alternately, calling

或者,调用

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

Will use the http_proxyenvironment variable

将使用http_proxy环境变量

回答by Alexey Volodko

I bought private proxy server, after purchase I got:

我购买了私人代理服务器,购买后我得到:

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

And I wanted to use it. First answerand second answerworked only for http(proxy) -> http(destination), however I wanted http(proxy) -> https(destination).

我想使用它。第一个答案第二个答案仅适用于 http(proxy) -> http(destination),但是我想要 http(proxy) -> https(destination)。

And for https destination it would be better to use HTTP tunneldirectly. I found solution here. Final code:

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

回答by Chris Kimpton

The 'request' http package seems to have this feature:

“请求”http 包似乎具有此功能:

https://github.com/mikeal/request

https://github.com/mikeal/request

For example, the 'r' request object below uses localproxy to access its requests:

例如,下面的“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)
  }
})

Unfortunately there are no "global" defaults so that users of libs that use this cannot amend the proxy unless the lib pass through http options...

不幸的是,没有“全局”默认值,因此使用它的库的用户无法修改代理,除非库通过 http 选项...

HTH, Chris

HTH,克里斯

回答by Renat

Basically you don't need an explicit proxy support. Proxy protocol is pretty simple and based on the normal HTTP protocol. You just need to use your proxy host and port when connecting with HTTPClient. Example (from node.js docs):

基本上你不需要明确的代理支持。代理协议非常简单,基于普通的 HTTP 协议。您只需要在与 HTTPClient 连接时使用您的代理主机和端口。示例(来自 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();
...

So basically you connect to your proxy but do a request to "http://www.google.com".

所以基本上你连接到你的代理,但请求“http://www.google.com”。

回答by Vyacheslav Voronchuk

In case you need to the use basic authorisation for your proxy provider, just use the following:

如果您需要为您的代理提供商使用基本授权,只需使用以下内容:

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

回答by Luke

Node should support using the http_proxy environmental variable - so it is cross platform and works on system settings rather than requiring a per-application configuration.

Node 应该支持使用 http_proxy 环境变量 - 所以它是跨平台的并且适用于系统设置而不需要每个应用程序的配置。

Using the provided solutions, I would recommend the following:

使用提供的解决方案,我会推荐以下内容:

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

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

UsageTo use the method, effectively just replace http.get, for instance the following writes the index page of google to a file called test.htm:

用法要使用该方法,只需替换 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"