From 58fa0dc0648d4eec88c3cf8ae90fcc932a42eafd Mon Sep 17 00:00:00 2001 From: cmliu Date: Wed, 12 Nov 2025 02:00:34 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BC=98=E5=8C=96=E8=AF=B7=E6=B1=82?= =?UTF-8?q?=E4=BC=98=E9=80=89API=E7=9A=84=E7=BC=96=E7=A0=81=E5=A4=84?= =?UTF-8?q?=E7=90=86=E9=80=BB=E8=BE=91=EF=BC=8C=E5=A2=9E=E5=BC=BA=E8=A7=A3?= =?UTF-8?q?=E7=A0=81=E6=88=90=E5=8A=9F=E7=8E=87=E5=B9=B6=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- _worker.js | 51 +++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 41 insertions(+), 10 deletions(-) diff --git a/_worker.js b/_worker.js index 3084d22..37cb69a 100644 --- a/_worker.js +++ b/_worker.js @@ -1359,20 +1359,51 @@ async function 请求优选API(urls, 默认端口 = '443', 超时时间 = 3000) const timeoutId = setTimeout(() => controller.abort(), 超时时间); const response = await fetch(url, { signal: controller.signal }); clearTimeout(timeoutId); - // 处理编码问题:支持 UTF-8 和 GB2312 编码 let text = ''; try { const buffer = await response.arrayBuffer(); - const charset = (response.headers.get('content-type') || '').match(/charset=([^\s;]+)/i)?.[1]?.toLowerCase() || ''; - const decoders = charset.match(/gb/) ? ['gb2312', 'utf-8'] : ['utf-8', 'gb2312']; - for (const dec of decoders) { - try { - text = new TextDecoder(dec).decode(buffer); - if (dec === 'utf-8' && (text.includes('�') || (text.length > 0 && /[\x80-\xFF]/.test(text) && !text.includes('中')))) continue; - break; - } catch { } + const contentType = (response.headers.get('content-type') || '').toLowerCase(); + const charset = contentType.match(/charset=([^\s;]+)/i)?.[1]?.toLowerCase() || ''; + + // 根据 Content-Type 响应头判断编码优先级 + let decoders = ['utf-8', 'gb2312']; // 默认优先 UTF-8 + if (charset.includes('gb') || charset.includes('gbk') || charset.includes('gb2312')) { + decoders = ['gb2312', 'utf-8']; // 如果明确指定 GB 系编码,优先尝试 GB2312 } - } catch { text = await response.text() } + + // 尝试多种编码解码 + let decodeSuccess = false; + for (const decoder of decoders) { + try { + const decoded = new TextDecoder(decoder).decode(buffer); + // 验证解码结果的有效性 + if (decoded && decoded.length > 0 && !decoded.includes('\ufffd')) { + text = decoded; + decodeSuccess = true; + break; + } else if (decoded && decoded.length > 0) { + // 如果有替换字符 (U+FFFD),说明编码不匹配,继续尝试下一个编码 + continue; + } + } catch (e) { + // 该编码解码失败,尝试下一个 + continue; + } + } + + // 如果所有编码都失败或无效,尝试 response.text() + if (!decodeSuccess) { + text = await response.text(); + } + + // 如果返回的是空或无效数据,返回 + if (!text || text.trim().length === 0) { + return; + } + } catch (e) { + console.error('Failed to decode response:', e); + return; + } const lines = text.trim().split('\n').map(l => l.trim()).filter(l => l); const isCSV = lines.length > 1 && lines[0].includes(','); const IPV6_PATTERN = /^[^\[\]]*:[^\[\]]*:[^\[\]]/;