使用Got库结合代理发送HTTP请求未生效,如何验证代理隧道?
代理请求验证与问题排查
我使用Got库结合代理发送HTTP请求,但调用IP查询服务时返回的不是代理IP,需要验证代理是否正常工作、确认请求是否通过代理隧道传输。以下是我的代码:
var got = require('got'); var hpagent = require('hpagent'); var ProxyLists = require('proxy-lists'); async function test(){ let proxiesArray = []; ProxyLists.getProxies({ countries: ['us', 'ca'] }) .on('data', function(proxies) { proxiesArray = proxiesArray.concat(proxies.filter(p=>p.protocols.includes("https"))); }) .on('error', function(error) {}) .once('end', function() { console.log('end!'); }); while(proxiesArray.length == 0) await utils.delay(1); let ip = proxiesArray[0].ipAddress; let port = proxiesArray[0].port; console.log(ip + ":" + port); let res = got('https://api.ipify.org?format=json', { agent: { https: new hpagent.HttpProxyAgent({ rejectUnauthorized: false, proxy: `https://${ip}:${port}` }) } }).then((body) => { console.log(body) }).catch((e) => { console.log('Error with proxy ' + proxy) }); }
一、验证代理是否正常工作
- 直接命令行测试:用
curl工具直接测试代理可用性,替换成你的代理IP和端口:
如果返回代理IP,说明代理本身可用;如果返回本地IP或报错,说明代理无效、不可达或协议不匹配。curl -x https://[代理IP]:[端口] https://api.ipify.org?format=json - 检查代理协议兼容性:确保代理支持的协议与请求协议匹配——如果目标是HTTPS请求,代理必须支持HTTPS(或HTTP代理支持CONNECT方法)。
- 测试CONNECT方法:HTTPS请求需要代理支持CONNECT隧道,可以用以下命令测试:
如果返回telnet [代理IP] [端口] # 连接后输入: CONNECT api.ipify.org:443 HTTP/1.1 Host: api.ipify.org:443HTTP/1.1 200 Connection established,说明代理支持CONNECT。
二、确认请求是否通过代理传输
- 改用详细信息接口:把目标地址换成
https://httpbin.org/get,它会返回请求的完整信息,包括origin字段(显示来源IP)和headers中的代理相关字段,通过这些信息可以直接判断是否走了代理。 - 添加请求钩子日志:在Got的配置中添加
hooks,打印请求的代理配置和连接信息:got('https://httpbin.org/get', { agent: { /* 代理配置 */ }, hooks: { beforeRequest: [options => { console.log('使用的代理配置:', options.agent.https.proxy); }] } }) - 抓包监控网络:用Wireshark或Charles等工具抓包,查看请求的目标IP是否是代理IP,而非
api.ipify.org的IP(HTTPS请求会先向代理发送CONNECT请求)。
三、代码中的问题修正
异步逻辑问题:
ProxyLists.getProxies是事件驱动的,当前的while循环等待方式不可靠,建议封装成Promise:function getProxies() { return new Promise((resolve, reject) => { const proxiesArray = []; ProxyLists.getProxies({ countries: ['us', 'ca'] }) .on('data', proxies => { proxiesArray.push(...proxies.filter(p => p.protocols.includes("https"))); }) .on('error', reject) .on('end', () => resolve(proxiesArray)); }); }然后在
test函数中用await getProxies()获取代理列表。代理Agent不匹配:如果使用HTTPS代理,应该用
hpagent.HttpsProxyAgent而非HttpProxyAgent,修正后:https: new hpagent.HttpsProxyAgent({ rejectUnauthorized: false, proxy: `https://${ip}:${port}` })未定义变量修复:
catch块中的proxy变量未定义,改为:.catch((e) => { console.log(`Error with proxy ${ip}:${port}`, e.message); })依赖问题:确保
utils.delay存在,或者替换为自定义的delay函数:const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
修正后的完整代码示例:
var got = require('got'); var hpagent = require('hpagent'); var ProxyLists = require('proxy-lists'); const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); function getProxies() { return new Promise((resolve, reject) => { const proxiesArray = []; ProxyLists.getProxies({ countries: ['us', 'ca'] }) .on('data', proxies => { proxiesArray.push(...proxies.filter(p => p.protocols.includes("https"))); }) .on('error', reject) .on('end', () => resolve(proxiesArray)); }); } async function test(){ let proxiesArray = await getProxies(); if (proxiesArray.length === 0) { console.log('未获取到可用代理'); return; } let ip = proxiesArray[0].ipAddress; let port = proxiesArray[0].port; console.log('使用代理:', `${ip}:${port}`); try { let res = await got('https://httpbin.org/get', { agent: { https: new hpagent.HttpsProxyAgent({ rejectUnauthorized: false, proxy: `https://${ip}:${port}` }) }, hooks: { beforeRequest: [options => { console.log('代理配置:', options.agent.https.proxy); }] } }); console.log('返回结果:', JSON.parse(res.body)); } catch (e) { console.log(`代理 ${ip}:${port} 请求失败`, e.message); } } test();
内容的提问来源于stack exchange,提问作者dvrer
相关产品推荐
相关产品推荐

