diff --git a/src/app/service/service_worker/script.ts b/src/app/service/service_worker/script.ts index fd669b14e..705543d13 100644 --- a/src/app/service/service_worker/script.ts +++ b/src/app/service/service_worker/script.ts @@ -162,39 +162,123 @@ export class ScriptService { } ); // 兼容 chrome 内核 < 128 处理 - const condition: chrome.declarativeNetRequest.RuleCondition = { - regexFilter: "^([^#]+?)\\.user(\\.bg|\\.sub)?\\.js((\\?).*|$)", - resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], - requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], - }; const browserType = getBrowserType(); - if (browserType.chrome && browserType.chromeVersion >= 128) { - condition.excludedResponseHeaders = [ - { - header: "Content-Type", - values: ["text/html"], + const addResponseHeaders = browserType.chrome && browserType.chromeVersion >= 128; + // Chrome 84+ + const conditions: chrome.declarativeNetRequest.RuleCondition[] = [ + { + regexFilter: "^([^?#]+?\\.user(\\.bg|\\.sub)?\\.js)", // Chrome 84+ + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], // Chrome 84+ + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], // Chrome 91+ + isUrlFilterCaseSensitive: false, // Chrome 84+ + excludedRequestDomains: ["github.com", "gitlab.com", "gitea.com", "bitbucket.org"], // Chrome 101+ + }, + { + regexFilter: "^(.+?\\.user(\\.bg|\\.sub)?\\.js&response-content-type=application%2Foctet-stream)", + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], // Chrome 91+ + isUrlFilterCaseSensitive: false, + requestDomains: ["githubusercontent.com"], // Chrome 101+ + }, + { + regexFilter: + "^(https?:\\/\\/github.com\\/[^\\s/?#]+\\/[^\\s/?#]+\\/releases/[^\\s/?#]+/download/[^?#]+?\\.user(\\.bg|\\.sub)?\\.js)", + // https://github.com///releases/latest/download/file.user.js + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], // Chrome 91+ + isUrlFilterCaseSensitive: false, + requestDomains: ["github.com"], // Chrome 101+ + }, + { + regexFilter: + "^(https?:\\/\\/gitlab\\.com\\/[^\\s/?#]+\\/[^\\s/?#]+\\/-\\/raw\\/[a-z0-9_/.-]+\\/[^?#]+?\\.user(\\.bg|\\.sub)?\\.js)", + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], // Chrome 91+ + isUrlFilterCaseSensitive: false, + requestDomains: ["gitlab.com"], // Chrome 101+ + }, + { + regexFilter: "^(https?:\\/\\/github\\.com\\/[^\\/]+\\/[^\\/]+\\/releases\\/[^?#]+?\\.user(\\.bg|\\.sub)?\\.js)", + // https://github.com///releases/latest/download/file.user.js + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], // Chrome 91+ + isUrlFilterCaseSensitive: false, + requestDomains: ["github.com"], // Chrome 101+ + }, + { + regexFilter: "^(https?://github.com/[^\\s/?#]+/[^\\s/?#]+/raw/[a-z]+/[^?#]+?.user(\\.bg|\\.sub)?.js)", + // https://github.com///raw/refs/heads/main/.../file.user.js + // https://github.com///raw//.../file.user.js + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], // Chrome 91+ + isUrlFilterCaseSensitive: false, + requestDomains: ["github.com"], // Chrome 101+ + }, + { + regexFilter: + "^(https?://gitlab\\.com/[^\\s/?#]+/[^\\s/?#]+/-/raw/[a-z0-9_/.-]+/[^?#]+?\\.user(\\.bg|\\.sub)?\\.js)", + // https://gitlab.com///-/raw//.../file.user.js + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], + isUrlFilterCaseSensitive: false, + requestDomains: ["gitlab.com"], // Chrome 101+ + }, + { + regexFilter: + "^(https?://gitea\\.com/[^\\s/?#]+/[^\\s/?#]+/raw/[a-z0-9_/.-]+/[^?#]+?\\.user(\\.bg|\\.sub)?\\.js)", + // https://gitea.com///raw//.../file.user.js + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], + isUrlFilterCaseSensitive: false, + requestDomains: ["gitea.com"], // Chrome 101+ + }, + { + regexFilter: + "^(https?://bitbucket\\.org/[^\\s/?#]+/[^\\s/?#]+/raw/[a-z0-9_/.-]+/[^?#]+?\\.user(\\.bg|\\.sub)?\\.js)", + // https://bitbucket.org///raw//.../file.user.js + resourceTypes: [chrome.declarativeNetRequest.ResourceType.MAIN_FRAME], + requestMethods: ["get" as chrome.declarativeNetRequest.RequestMethod], + isUrlFilterCaseSensitive: false, + requestDomains: ["bitbucket.org"], // Chrome 101+ + }, + ]; + const rules = conditions.map((condition, idx) => { + Object.assign(condition, { + excludedTabIds: [chrome.tabs.TAB_ID_NONE], + }); + if (addResponseHeaders) { + Object.assign(condition, { + responseHeaders: [ + { + header: "Content-Type", + values: [ + "text/javascript*", + "application/javascript*", + "text/html*", + "text/plain*", + "application/octet-stream*", + "application/force-download*", + ], + }, + ], + }); + } + return { + id: 1000 + idx, + priority: 1, + action: { + type: "redirect" as chrome.declarativeNetRequest.RuleActionType, + redirect: { + regexSubstitution: `${DocumentationSite}${localePath}/docs/script_installation/#url=\\1`, + }, }, - ]; - } else { - condition.excludedRequestDomains = ["github.com"]; - } + condition: condition, + } as chrome.declarativeNetRequest.Rule; + }); // 重定向到脚本安装页 chrome.declarativeNetRequest.updateDynamicRules( { - removeRuleIds: [1, 2], - addRules: [ - { - id: 1, - priority: 1, - action: { - type: "redirect" as chrome.declarativeNetRequest.RuleActionType, - redirect: { - regexSubstitution: `${DocumentationSite}${localePath}/docs/script_installation/#url=\\0`, - }, - }, - condition: condition, - }, - ], + removeRuleIds: [1], }, () => { if (chrome.runtime.lastError) { @@ -205,6 +289,20 @@ export class ScriptService { } } ); + chrome.declarativeNetRequest.updateSessionRules( + { + removeRuleIds: [...rules.map((rule) => rule.id)], + addRules: rules, + }, + () => { + if (chrome.runtime.lastError) { + console.error( + "chrome.runtime.lastError in chrome.declarativeNetRequest.updateSessionRules:", + chrome.runtime.lastError + ); + } + } + ); } public async openInstallPageByUrl(url: string, source: InstallSource): Promise<{ success: boolean; msg: string }> {