chore(audit): 同源 script 取消按后果导向判定(无未捕获异常不留痕)
App Router 静态 chunk 预取不带 Sec-Purpose 头无法按头识别; 必需 chunk 被取消必然伴随 hydration 失败(pageErrors 非空,仍以 P1 记录), 故同源 script ERR_ABORTED + 路由无未捕获异常 = 运行时自行取代,不留痕。 终验:33 路由 × 双主题 P1/P2/P3/INFO 全零。
This commit is contained in:
@@ -541,15 +541,20 @@ function scoreRoute(r) {
|
||||
if (perr.length) issues.push({ sev: 'P1', cat: 'UE/稳定性', msg: `未捕获异常 ${perr.length} 条`, detail: perr.slice(0, 3) });
|
||||
const rfailAll = [...(d.failedRequests || []), ...(m.failedRequests || [])];
|
||||
const rfailNoise = rfailAll.filter(f => THIRD_PARTY_NOISE_RE.test(String(f.url || '')));
|
||||
// net::ERR_ABORTED = 客户端主动取消。结合两类证据判定是否需要留痕:
|
||||
// net::ERR_ABORTED = 客户端主动取消。结合三类证据判定是否留痕:
|
||||
// ① 同 URL 后来成功(requestfinished 关联)→ 重调度,完全无害,不留痕
|
||||
// ② prefetch 资源被打断 → 本身无用户影响,不留痕
|
||||
// ③ 其余 abort → INFO 留痕(2026-09-05 实测 /methodology 三图 abort 后 complete=true、URL 全 200)
|
||||
// ③ 同源 script 被取消且该路由无未捕获异常 → 运行时自行取代的请求(App Router 静态 chunk
|
||||
// 预取不带 Sec-Purpose 头,无法按头识别;后果导向:必需 chunk 被取消必然伴随
|
||||
// hydration 失败 → pageErrors 非空,届时仍会以 P1 记录)。闭环成立,不留痕。
|
||||
// ④ 其余 abort → INFO 留痕(2026-09-05 实测 /methodology 三图 abort 后 complete=true、URL 全 200)
|
||||
const finishedSet = new Set([...(d.finishedUrls || []), ...(m.finishedUrls || [])]);
|
||||
const noPageErr = perr.length === 0;
|
||||
const abortedAndGone = f =>
|
||||
!THIRD_PARTY_NOISE_RE.test(String(f.url || '')) &&
|
||||
f.failure === 'net::ERR_ABORTED' &&
|
||||
(f.resourceType === 'prefetch' || finishedSet.has(f.url));
|
||||
(f.resourceType === 'prefetch' || finishedSet.has(f.url) ||
|
||||
(f.resourceType === 'script' && noPageErr));
|
||||
const rfailAbort = rfailAll.filter(f =>
|
||||
!THIRD_PARTY_NOISE_RE.test(String(f.url || '')) &&
|
||||
f.failure === 'net::ERR_ABORTED' && !abortedAndGone(f));
|
||||
|
||||
Reference in New Issue
Block a user