如何在 node.js 中同时使用多个代理(代理)
Posted
技术标签:
【中文标题】如何在 node.js 中同时使用多个代理(代理)【英文标题】:How to use multiple proxies (agents) at the same time in node.js 【发布时间】:2020-11-22 13:26:12 【问题描述】:我正在使用一个 HTTP 请求库,它可以使用 http.Agent 实例来通过特定代理路由您的请求。 举个例子吧:
const SocksProxyAgent = require('socks-proxy-agent')
const HttpProxyAgent = require('http-proxy-agent') // not used
const axios = require('axios')
// requires Tor service to be running
const torProxyAgent = new SocksProxyAgent('socks://circuit1@127.0.0.1:9050')
// not used
const otherProxyAgent = new HttpProxyAgent('http://admin:1234@localhost:8888')
const axiosConfig =
httpsAgent: torProxyAgent,
httpAgent: torProxyAgent
const axiosInstance = axios.create(axiosConfig)
axiosInstance.get('https://ifconfig.io/ip')
.then(res =>
console.log('Public IP address:', res.data)
).catch(err =>
console.log(err)
)
如您所见,我指定了多个代理(torProxyAgent
和 otherProxyAgent
),但我只能使用一个。
所以我正在寻找一种超级代理,我可以将它传递给我的 HTTP 请求库,然后这个超级代理将任意数量的普通代理链接在一起,方法是将我的所有请求通过第一个路由,然后通过第二个,然后通过第三个等等......
这可能吗?有没有现成的解决方案?
有没有办法使用Proxy 类创建一个假代理,将所有方法调用传递给一个代理,然后再传递给第二个代理?
编辑: 虽然我很欣赏lifeisfoo's answer,但它只解决了一个理论上的问题,即我碰巧只使用了两个代理(一个 HTTP 代理和一个 socks 代理)。实际上,我不想局限于两个代理,我希望能够指定顺序。
【问题讨论】:
你为什么要做这个?你想达到什么结果?通过多个节点传递连接? 是的,我希望能够创建支持不同类型代理的代理链,例如 socks 和 http 代理。例如。 PC->Tor-socks-proxy->HTTP-proxy->服务器 我更新了我的答案,这应该可以解决你的问题 【参考方案1】:更新答案 - axios + socks-proxy-agent + http 代理
看起来解决方案比我想象的要容易:
const SocksProxyAgent = require('socks-proxy-agent')
const axios = require('axios')
const torProxyAgent = new SocksProxyAgent('socks://circuit1@127.0.0.1:9050')
const axiosConfig =
httpsAgent: torProxyAgent,
httpAgent: torProxyAgent,
proxy:
protocol: 'http', //'http',
host: '89.208.35.81', // your http proxy ip
port: 3128, // your http proxy port
// optional - add it if your proxy require auth
auth:
username: 'myuser',
password: 'mypass'
const axiosInstance = axios.create(axiosConfig)
axiosInstance.get('https://ifconfig.io/ip')
.then(res =>
console.log('Public IP address:', res.data)
).catch(err =>
console.log(err)
)
确保仅当您的 socks 代理在本地运行时才使用 localhost HTTP 代理,否则将无法访问。显然,socks 和代理 IP 应该更新为可用的,我使用在 public proxy list 上找到的一些 IP 作为测试,但它们不可靠。
工作原理
Agent 的 nodejs 文档 sasys:
[...] 负责管理 HTTP 客户端的连接持久性和重用。它为给定的主机和端口维护一个待处理的请求队列,为每个请求重用一个套接字连接,直到队列为空。
基本上,它公开了一个返回套接字的createConnection 函数:
此方法保证返回
类的实例, 的子类,除非用户指定 以外的套接字类型。
这种行为如果你查看另一个像socks5-http-client/lib/Agent这样的socks代理的源代码很容易看出:
var http = require('http');
var inherits = require('util').inherits;
var socksClient = require('socks5-client');
function Agent(options)
http.Agent.call(this, options);
this.createConnection = socksClient.createConnection;
inherits(Agent, http.Agent);
module.exports = Agent;
尝试调试请求流,你会看到socks连接数据和http数据都写在了socket上。添加断点或登录Socks5ClientSocket.prototype.write function
Socks5ClientSocket.prototype.write = function(data, encoding, cb)
console.log('Writing', data);
return this.socket.write(data, encoding, cb);
;
你会看到这样的东西:
Writing <Buffer 05 01 00>
Writing <Buffer 05 01 00 01 59 d0 23 51 0c 38>
Writing GET http://ip-api.com/json HTTP/1.1 ....// http request data
前两行是建立socks connection到socks代理的字节,然后将http数据写入同一个套接字但使用http代理作为目标主机。
因此,从 http 库的角度来看,代理只是 socket 提供者,因此您可以根据需要创建此套接字,可能在同一个套接字上链接更多连接(请参阅我的原始答案)。
axios + socks5-http-client + http 代理
var Agent = require('socks5-http-client/lib/Agent');
var axios = require('axios');
const socksProxyOpts =
socksHost: '5.189.130.21',
socksPort: 1080
;
const socksAgent = new Agent(socksProxyOpts);
const axiosConfig =
httpAgent: socksAgent,
proxy:
protocol: 'http',
host: '89.208.35.81',// or '45.33.99.194',
port: 3128 // or 8888
const axiosInstance = axios.create(axiosConfig)
axiosInstance.get('http://ip-api.com/json')
.then(res =>
console.log('Public IP address:', res.data)
).catch(err =>
console.log(err)
)
原答案
是的,您可以从这个C proxychains application 和它的configuration file 看到:
[ProxyList]
# based on you configuration
socks4 127.0.0.1 9050 circuit1
http localhost 8888 admin 1234
但似乎没有现有的节点模块能够处理一系列混合类型的代理(socks、http)。
socks 库可以处理 chain of socks proxies,但此功能 isn't already exposed 可以处理您正在使用的 socks-proxy-agent。
可以使用http-proxy 和来自此gist 的代码来实现http 代理链。
所以你有三个选择:
使用现有的proxychains application 使用socks 使用一系列袜子代理 破解 socks 库以在链中添加对 http 代理的支持如果您选择最后一个,请务必查看 createConnectionChain
函数 for the chain creation logic 的 socks 库源代码。
另见:
[斯卡拉]https://github.com/Karasiq/proxychain [锈]https://github.com/eycorsican/leaf [JS]https://www.npmjs.com/package/tunnel【讨论】:
以上是关于如何在 node.js 中同时使用多个代理(代理)的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 Node.js 通过代理发送 HTTP/2 请求?
基于 Unix Socket 的可靠 Node.js HTTP 代理实现(支持 WebSocket 协议)