429 字
2 分钟
混合代理脚本
```javascript
2026-03-15
无标签
统计加载中...
const http = require('http');const httpProxy = require('http-proxy');const tunnel = require('tunnel');const { SocksProxyAgent } = require('socks');
// -------------------------- 配置区 --------------------------const LISTEN_PORT = 3000;const PROXY_POOL = [ 'socks5://user1:pass1@proxy1.example.com:1080', 'https://user2:pass2@proxy2.example.com:443', 'socks5://proxy3.example.com:1080', 'https://proxy4.example.com:8443'];let currentIndex = 0;const MAX_RETRY = PROXY_POOL.length;const REQUEST_TIMEOUT = 800 * 1000; // 超时时间设置为 800 秒(转为毫秒)// -------------------------- 配置区结束 --------------------------
const proxy = httpProxy.createProxyServer({});
function getAgentByIndex(index) { const proxyUrl = PROXY_POOL[index]; const urlObj = new URL(proxyUrl);
if (urlObj.protocol === 'socks5:') { return new SocksProxyAgent(proxyUrl, { timeout: REQUEST_TIMEOUT }); } else if (urlObj.protocol === 'https:') { const proxyOpts = { host: urlObj.hostname, port: parseInt(urlObj.port), proxyAuth: urlObj.username && urlObj.password ? `${urlObj.username}:${urlObj.password}` : undefined, timeout: REQUEST_TIMEOUT }; return tunnel.httpsOverHttps({ proxy: proxyOpts }); } throw new Error(`不支持的代理协议: ${urlObj.protocol}`);}
function getNextIndex() { currentIndex = (currentIndex + 1) % PROXY_POOL.length; return currentIndex;}
function handleHttpRequestWithRetry(req, res, retryCount = 0) { if (retryCount >= MAX_RETRY) { res.writeHead(500, { 'Content-Type': 'text/plain' }); return res.end(`所有代理均不可用,重试次数: ${retryCount}`); }
const currentTryIndex = (currentIndex + retryCount) % PROXY_POOL.length; const agent = getAgentByIndex(currentTryIndex);
try { proxy.web(req, res, { target: req.url, agent, prependPath: false, changeOrigin: true, timeout: REQUEST_TIMEOUT // HTTP 请求转发超时 });
proxy.once('proxyRes', () => { getNextIndex(); }); } catch (err) { console.error(`代理 ${PROXY_POOL[currentTryIndex]} 失败: ${err.message}`); handleHttpRequestWithRetry(req, res, retryCount + 1); }}
function handleHttpsConnectWithRetry(req, socket, head, retryCount = 0) { if (retryCount >= MAX_RETRY) { socket.write('HTTP/1.1 500 All Proxies Unavailable\r\n\r\n'); return socket.end(); }
const currentTryIndex = (currentIndex + retryCount) % PROXY_POOL.length; const agent = getAgentByIndex(currentTryIndex); const [host, port] = req.url.split(':'); const opts = { host, port: port || 443, timeout: REQUEST_TIMEOUT // HTTPS 隧道连接超时 };
agent.createConnection(opts, (err, conn) => { if (err) { console.error(`代理 ${PROXY_POOL[currentTryIndex]} 失败: ${err.message}`); return handleHttpsConnectWithRetry(req, socket, head, retryCount + 1); }
socket.write('HTTP/1.1 200 Connection Established\r\n\r\n'); conn.write(head); conn.pipe(socket); socket.pipe(conn); getNextIndex(); });}
const server = http.createServer((req, res) => { handleHttpRequestWithRetry(req, res);});
server.on('connect', (req, socket, head) => { handleHttpsConnectWithRetry(req, socket, head);});
proxy.on('error', (err, req, res) => { if (!res.headersSent) { const retryCount = parseInt(req.headers['x-retry-count'] || 0) + 1; req.headers['x-retry-count'] = retryCount; handleHttpRequestWithRetry(req, res, retryCount); }});
server.listen(LISTEN_PORT, () => { console.log(`✅ 带失败重试的混合代理服务启动: http://localhost:${LISTEN_PORT}`); console.log(`🔄 代理池(${PROXY_POOL.length}个): ${PROXY_POOL.join(', ')}`); console.log(`⏱️ 请求超时时间: ${REQUEST_TIMEOUT / 1000} 秒`); console.log(`🔧 最大重试次数: ${MAX_RETRY}`);});发现错误或想要改进这篇文章?
在 GitHub 上编辑此页