Skip to content

Commit d80bc08

Browse files
committed
改善 session rule 移除处理 及 scXhrRequests 处理
1 parent da33bd2 commit d80bc08

1 file changed

Lines changed: 86 additions & 23 deletions

File tree

  • src/app/service/service_worker/gm_api

src/app/service/service_worker/gm_api/gm_api.ts

Lines changed: 86 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,42 @@ const generateUniqueMarkerID = () => {
7575
};
7676

7777
type OnBeforeSendHeadersOptions = `${chrome.webRequest.OnBeforeSendHeadersOptions}`;
78-
type OnHeadersReceivedOptions = `${chrome.webRequest.OnHeadersReceivedOptions}`;
78+
type ReceiveHeaderOptions = `${chrome.webRequest.OnHeadersReceivedOptions}` &
79+
`${chrome.webRequest.OnResponseStartedOptions}`;
80+
81+
// 删除关联与DNR: 不再处理 headerModifer 时清空 Map 关联 及 浏览器 Session Rule
82+
const headersSettled = (markerID: string) => {
83+
const dnrRule = headerModifierMap.get(markerID);
84+
const ruleID = dnrRule?.rule.id;
85+
if (markerID) {
86+
headerModifierMap.delete(markerID);
87+
}
88+
if (ruleID) {
89+
chrome.declarativeNetRequest.updateSessionRules(
90+
{
91+
removeRuleIds: [ruleID],
92+
},
93+
() => {
94+
const lastError = chrome.runtime.lastError;
95+
if (lastError) {
96+
console.error("chrome.declarativeNetRequest.updateSessionRules:", lastError);
97+
}
98+
removeSessionRuleIdEntry(ruleID);
99+
}
100+
);
101+
}
102+
};
103+
104+
const cleanupOnAPIError = (requestId: string) => {
105+
const markerID = scXhrRequests.get(requestId) as string | undefined;
106+
scXhrRequests.delete(requestId);
107+
if (!markerID) return;
108+
redirectedUrls.delete(markerID);
109+
nwErrorResults.delete(markerID);
110+
scXhrRequests.delete(markerID);
111+
headersReceivedMap.delete(markerID);
112+
headersSettled(markerID); // 处理完毕
113+
};
79114

80115
// GMExternalDependencies接口定义
81116
// 为了支持外部依赖注入,方便测试和扩展
@@ -851,7 +886,7 @@ export default class GMApi {
851886
if (reqId) scXhrRequests.delete(reqId);
852887
scXhrRequests.delete(markerID);
853888
headersReceivedMap.delete(markerID);
854-
headerModifierMap.delete(markerID);
889+
headersSettled(markerID); // 处理完毕
855890
};
856891
let strategy: GMXhrStrategy | undefined = undefined;
857892
if (useFetch) {
@@ -1410,6 +1445,7 @@ export default class GMApi {
14101445
if (lastError) {
14111446
console.error("chrome.runtime.lastError in chrome.webRequest.onBeforeRedirect:", lastError);
14121447
// webRequest API 出错不进行后续处理
1448+
cleanupOnAPIError(details?.requestId);
14131449
return undefined;
14141450
}
14151451
if (details.tabId === -1) {
@@ -1426,7 +1462,7 @@ export default class GMApi {
14261462
}
14271463
);
14281464
const reqOpt: OnBeforeSendHeadersOptions[] = ["requestHeaders"];
1429-
const respOpt: OnHeadersReceivedOptions[] = ["responseHeaders"];
1465+
const respOpt: ReceiveHeaderOptions[] = ["responseHeaders"];
14301466
if (!isFirefox()) {
14311467
reqOpt.push("extraHeaders");
14321468
respOpt.push("extraHeaders");
@@ -1438,14 +1474,16 @@ export default class GMApi {
14381474
if (lastError) {
14391475
console.error("chrome.runtime.lastError in chrome.webRequest.onErrorOccurred:", lastError);
14401476
// webRequest API 出错不进行后续处理
1477+
cleanupOnAPIError(details?.requestId);
14411478
return undefined;
14421479
}
14431480
if (details.tabId === -1) {
14441481
const markerID = scXhrRequests.get(details.requestId);
1445-
if (markerID) {
1446-
nwErrorResults.set(markerID, details.error);
1447-
nwErrorResultPromises.get(markerID)?.();
1448-
}
1482+
if (!markerID) return;
1483+
nwErrorResults.set(markerID, details.error);
1484+
nwErrorResultPromises.get(markerID)?.();
1485+
1486+
headersSettled(markerID); // 错误发生,不处理 header modifiers
14491487
}
14501488
},
14511489
{
@@ -1502,6 +1540,7 @@ export default class GMApi {
15021540
if (lastError) {
15031541
console.error("chrome.runtime.lastError in chrome.webRequest.onBeforeSendHeaders:", lastError);
15041542
// webRequest API 出错不进行后续处理
1543+
cleanupOnAPIError(details?.requestId);
15051544
return undefined;
15061545
}
15071546
if (details.tabId === -1) {
@@ -1510,7 +1549,11 @@ export default class GMApi {
15101549
if (requestHeaders) {
15111550
// 如 onBeforeSendHeaders 是在 modifyHeaders 前执行,可以更新一下 reqId 和 markerID 的关联
15121551
const markerID = requestHeaders?.find((h) => h.name.toLowerCase() === "x-sc-request-marker")?.value;
1513-
if (markerID) scXhrRequests.set(reqId, markerID);
1552+
if (markerID) {
1553+
// 双向关联
1554+
scXhrRequests.set(reqId, markerID);
1555+
scXhrRequests.set(markerID, reqId); // 用于清理
1556+
}
15141557
}
15151558
const markerID = scXhrRequests.get(reqId);
15161559
if (!markerID) return undefined;
@@ -1525,12 +1568,14 @@ export default class GMApi {
15251568
},
15261569
reqOpt
15271570
);
1571+
15281572
chrome.webRequest.onHeadersReceived.addListener(
15291573
(details) => {
15301574
const lastError = chrome.runtime.lastError;
15311575
if (lastError) {
15321576
console.error("chrome.runtime.lastError in chrome.webRequest.onBeforeSendHeaders:", lastError);
15331577
// webRequest API 出错不进行后续处理
1578+
cleanupOnAPIError(details?.requestId);
15341579
return undefined;
15351580
}
15361581
if (details.tabId === -1) {
@@ -1597,21 +1642,7 @@ export default class GMApi {
15971642
}
15981643
}
15991644
);
1600-
} else {
1601-
// 删除关联与DNR
1602-
headerModifierMap.delete(markerID);
1603-
chrome.declarativeNetRequest.updateSessionRules(
1604-
{
1605-
removeRuleIds: [rule.id],
1606-
},
1607-
() => {
1608-
const lastError = chrome.runtime.lastError;
1609-
if (lastError) {
1610-
console.error("chrome.declarativeNetRequest.updateSessionRules:", lastError);
1611-
}
1612-
removeSessionRuleIdEntry(rule.id);
1613-
}
1614-
);
1645+
return;
16151646
}
16161647
}
16171648
}
@@ -1624,6 +1655,38 @@ export default class GMApi {
16241655
respOpt
16251656
);
16261657

1658+
chrome.webRequest.onResponseStarted.addListener(
1659+
(details) => {
1660+
// onResponseStarted 触发后,headers 不会再有改动
1661+
const lastError = chrome.runtime.lastError;
1662+
if (lastError) {
1663+
console.error("chrome.runtime.lastError in chrome.webRequest.onResponseStarted:", lastError);
1664+
// webRequest API 出错不进行后续处理
1665+
cleanupOnAPIError(details?.requestId);
1666+
return undefined;
1667+
}
1668+
if (details.tabId === -1) {
1669+
const reqId = details.requestId;
1670+
1671+
const markerID = scXhrRequests.get(reqId);
1672+
if (!markerID) return;
1673+
if (details.responseHeaders && details.statusCode) {
1674+
headersReceivedMap.set(markerID, {
1675+
responseHeaders: details.responseHeaders,
1676+
statusCode: details.statusCode,
1677+
});
1678+
}
1679+
1680+
headersSettled(markerID); // onResponseStarted 已触发,headers 已固定
1681+
}
1682+
},
1683+
{
1684+
urls: ["<all_urls>"],
1685+
types: ["xmlhttprequest"],
1686+
},
1687+
respOpt
1688+
);
1689+
16271690
const ruleId = 999;
16281691
const rule = {
16291692
id: ruleId,

0 commit comments

Comments
 (0)