Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 126 additions & 28 deletions src/app/service/service_worker/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

responseHeaders与excludedResponseHeaders 都需要 >= 128 的版本,是不打算兼容旧版本的浏览器了么?(虽然我也想,恶心的兼容性) https://developer.chrome.com/docs/extensions/reference/api/declarativeNetRequest?hl=zh-cn#:~:text=main_frame%20%E8%B5%84%E6%BA%90%E7%B1%BB%E5%9E%8B%E3%80%82-,responseHeaders,-HeaderInfo%5B%5D%C2%A0%E5%8F%AF

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不使用 excludedResponseHeaders

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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)",
Copy link
Member

@CodFrm CodFrm Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这种应该是可以不匹配的(不过无所谓,可以少点规则)

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/<user>/<repo>/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/<user>/<repo>/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/<user>/<repo>/raw/refs/heads/main/.../file.user.js
// https://github.com/<user>/<repo>/raw/<branch>/.../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/<user>/<repo>/-/raw/<branch>/.../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/<user>/<repo>/raw/<branch>/.../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/<user>/<repo>/raw/<branch>/.../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) {
Expand All @@ -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 }> {
Expand Down
Loading