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 上编辑此页
混合代理脚本
https://blog.chaosyn.com/posts/混合代理脚本/
作者
花渐畔
发布于
2026-03-15
许可协议
CC BY-NC-SA 4.0