From b3506a292490e78c558148f2e7ebf46dfc19f58a Mon Sep 17 00:00:00 2001 From: cyfung1031 <44498510+cyfung1031@users.noreply.github.com> Date: Sun, 22 Mar 2026 11:36:06 +0900 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3=20fetchScriptBody=20?= =?UTF-8?q?=E7=9A=84=20Accept=20=E8=AE=BE=E5=AE=9A=EF=BC=8C=E9=81=BF?= =?UTF-8?q?=E5=85=8D=E8=A7=A6=E5=8F=91=20Error=20406?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/install/App.tsx | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/pages/install/App.tsx b/src/pages/install/App.tsx index 6bbb48d51..b9c4020c4 100644 --- a/src/pages/install/App.tsx +++ b/src/pages/install/App.tsx @@ -67,7 +67,8 @@ const fetchScriptBody = async (url: string, { onProgress }: { [key: string]: any const response = await fetch(url, { headers: { "Cache-Control": "no-cache", - Accept: "text/javascript,application/javascript,text/plain,application/octet-stream,application/force-download", + /* 不指定 application/octet-stream 和 application/force-download 避免触发伺服器端 Error 406 */ + Accept: "text/javascript, application/javascript, */*", // prefer JavaScript, but anything is acceptable // 参考:加权 Accept-Encoding 值说明 // https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Accept-Encoding#weighted_accept-encoding_values "Accept-Encoding": "br;q=1.0, gzip;q=0.8, *;q=0.1", @@ -83,8 +84,21 @@ const fetchScriptBody = async (url: string, { onProgress }: { [key: string]: any if (!response.body || !response.headers) { throw new Error("No response body or headers"); } - if (response.headers.get("content-type")?.includes("text/html")) { - throw new Error("Response is text/html, not a valid UserScript"); + const contentType = response.headers.get("content-type"); + + if (contentType) { + // 不接受非 JavaScript文本 的回应 + const contentTypeLower = contentType.toLowerCase(); + const m = /^\s*([\w-]+)[^\w-]+([\w-]+)/.exec(contentTypeLower); + if (m) { + const contentTypeOK = + (m[2] === "javascript" && (m[1] === "text" || m[1] === "application")) || + (m[1] === "application" && (m[2] === "octet-stream" || m[2] === "force-download")); + if (!contentTypeOK) { + throw new Error(`Response is ${contentType}, not a valid UserScript`); + // e.g. Response is text/html, not a valid UserScript + } + } } const reader = response.body.getReader(); @@ -113,7 +127,6 @@ const fetchScriptBody = async (url: string, { onProgress }: { [key: string]: any } // 检测编码:优先使用 Content-Type,回退到 chardet(仅检测前16KB) - const contentType = response.headers.get("content-type"); const encode = detectEncoding(chunksAll, contentType); // 使用检测到的 charset 解码