Files

119 lines
2.8 KiB
JavaScript
Raw Permalink Normal View History

2026-07-03 20:12:20 +08:00
/**
* CAPTCHA_PROXY 解析与 Chrome 代理注入(与 CapSolver AntiCloudflareTask 使用同一 IP
*
* 仅在实际检测到 CF 挑战、需要 Managed 过盾时由 server.js 显式启用(useCaptchaProxy=true)。
* 格式:ip:port:username:password
*/
const CAPTCHA_PROXY_RAW = (process.env.CAPTCHA_PROXY || '').trim();
/**
* @returns {{
* host: string,
* port: string,
* username: string,
* password: string,
* chromeProxyServer: string,
* capsolverString: string,
* }|null}
*/
function parseCaptchaProxy(raw = CAPTCHA_PROXY_RAW) {
const value = (raw || '').trim();
if (value === '') {
return null;
}
const parts = value.split(':');
if (parts.length < 4) {
return null;
}
const host = parts[0];
const port = parts[1];
const username = parts[2];
const password = parts.slice(3).join(':');
if (!host || !port || !username || !password) {
return null;
}
return {
host,
port,
username,
password,
chromeProxyServer: `http://${host}:${port}`,
capsolverString: value,
};
}
/** @returns {boolean} */
function hasCaptchaProxy() {
return parseCaptchaProxy() !== null;
}
/**
* 是否属于可能走 CapSolver Managed 的工单(A2C 等)
* 注意:仅表示候选,不代表本次任务一定挂代理
* @param {object|null|undefined} antiBot
*/
function isManagedCfCandidate(antiBot) {
if (!antiBot?.enabled) {
return false;
}
if (antiBot.cfChallengeMode === 'managed') {
return true;
}
if (antiBot.cfCloudflareSolver === true) {
return true;
}
return false;
}
/**
* @deprecated 请使用 isManagedCfCandidate + 显式 useCaptchaProxy 参数
*/
function shouldUseCaptchaProxyForAntiBot(antiBot) {
return false;
}
/**
* Chrome 启动参数 --proxy-server(须 useCaptchaProxy=true 时调用)
* @returns {string[]}
*/
function getCaptchaProxyChromeArgs() {
const parsed = parseCaptchaProxy();
if (!parsed) {
return [];
}
return [
`--proxy-server=${parsed.chromeProxyServer}`,
'--proxy-bypass-list=<-loopback>,localhost,127.0.0.1',
];
}
/**
* 为 Page 设置代理认证(须配合 --proxy-server
* @param {import('puppeteer').Page} page
* @returns {Promise<boolean>}
*/
async function applyCaptchaProxyToPage(page) {
const parsed = parseCaptchaProxy();
if (!parsed || !page) {
return false;
}
await page.authenticate({
username: parsed.username,
password: parsed.password,
});
return true;
}
module.exports = {
parseCaptchaProxy,
hasCaptchaProxy,
isManagedCfCandidate,
shouldUseCaptchaProxyForAntiBot,
getCaptchaProxyChromeArgs,
applyCaptchaProxyToPage,
};