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

Chr*_*erg 128 proxy http node.js

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

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

Sam*_*uel 146

关于使用HTTP代理,Tim Macfarlane答案很接近.

使用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);
});
Run Code Online (Sandbox Code Playgroud)

为了记录,他的答案与http://nodejs.org/一起使用,但那是因为他们的服务器并不关心主机头是不正确的.

  • 如何在选项块中集成代理用户和代理密码? (9认同)
  • 有没有办法使用http代理连接https端口?似乎没有简单的方法 (3认同)
  • @Gohan 请参阅下面 Chris 的回答,了解如何通过 http 代理连接到 https 服务器的示例。 (2认同)
  • 这有改变吗?即使最终目的地是另一台本地服务器,我也会收到“404”,并且目标服务器永远不会收到请求。 (2认同)

Ims*_*ull 50

您可以使用请求,我发现它在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);
  }
})
Run Code Online (Sandbox Code Playgroud)


Chr*_*ris 35

有一件事花了我一段时间来弄清楚,使用'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);
});
Run Code Online (Sandbox Code Playgroud)

  • +1你救了我!HTTP到代理的HTTPS请求. (3认同)

小智 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);
});
Run Code Online (Sandbox Code Playgroud)

  • 这似乎有效,虽然Fiddler称它为协议违规,这表明它不是一个正确的HTTP请求 - 通过代理...... (2认同)

maj*_*ann 11

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

require('global-tunnel').initialize({
  host: '10.0.0.10',
  port: 8080
});
Run Code Online (Sandbox Code Playgroud)

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

或者,打电话

require('global-tunnel').initialize();
Run Code Online (Sandbox Code Playgroud)

将使用http_proxy环境变量

  • 这对我有用!实际上这样你就可以将代理与代码分离,并使用npm的现有配置!这就是我要说的方式 (2认同)

Chr*_*ton 7

'request'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)
  }
})
Run Code Online (Sandbox Code Playgroud)

不幸的是,没有"全局"默认值,因此使用它的lib用户不能修改代理,除非lib通过http选项...

HTH,克里斯


Ren*_*nat 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();
...
Run Code Online (Sandbox Code Playgroud)

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

  • 不推荐使用http.createClient,Tim Macfarlane正在使用下面的较新的http.get (3认同)
  • 从 v5.6 开始,这显然不再适用于 Node.js,因为它们已经删除了 [createClient](http://nodejs.org/docs/v0.5.6/api/http.html#http.ClientResponse)。 (2认同)

Vya*_*huk 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();
Run Code Online (Sandbox Code Playgroud)


Ale*_*dko 5

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

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
Run Code Online (Sandbox Code Playgroud)

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

对于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
    }, (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()
Run Code Online (Sandbox Code Playgroud)

  • Nodejs 中没有记录 `socket` 属性。这个选项被删除了。 (2认同)