You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome扩展如何监听网络请求的canceled或unknown状态?

处理Chrome扩展中webRequest API未捕获的取消/未知状态请求

核心问题说明

Chrome的chrome.webRequest API自带的onCompleted、onErrorOccurred回调,没法覆盖所有请求终止场景——比如用户主动取消请求、页面跳转导致请求中断这类情况,这些场景不会触发现有回调,得额外加追踪逻辑。

你的两种方案评估与优化

方案1:performance.getEntriesByType("resource")

这个API的资源条目里,部分成功完成的请求会带responseStatus字段,但局限性很明显:

  • 中途取消的请求可能不会生成条目,就算有也拿不到状态
  • 跨域资源受CORS限制,无法获取完整状态
  • 只能拿到已完成的资源,没法实时追踪正在进行的请求
    所以这个方案不适合用来追踪取消/未知状态的请求。

方案2:请求Map+超时定时器(优化掉轮询)

你说的存Map加时间戳的思路完全可行,而且可以不用轮询,改用setTimeout更高效:

  1. 在onBeforeRequest里,用requestId作为唯一标识把请求存入Map,记录请求时间同时设个超时定时器(比如15秒,可按需调整)
  2. 当onCompleted或onErrorOccurred触发时,从Map里删掉对应请求并清除定时器
  3. 如果定时器触发时请求还在Map里,直接标记为「取消/未知状态」打日志,再删掉该请求

示例代码:

// 背景脚本中
const activeRequests = new Map();

chrome.webRequest.onBeforeRequest.addListener(
  (details) => {
    const requestId = details.requestId;
    // 设置15秒超时,超时后标记为无响应
    const timeoutTimer = setTimeout(() => {
      if (activeRequests.has(requestId)) {
        console.log(`请求已取消/状态未知: ${details.url}`);
        activeRequests.delete(requestId);
      }
    }, 15000);
    
    activeRequests.set(requestId, {
      url: details.url,
      startTime: Date.now(),
      timeoutTimer
    });
  },
  { urls: ["<all_urls>"] }, // 替换成你要监听的特定URL
  []
);

// 请求完成时清理资源
chrome.webRequest.onCompleted.addListener(
  (details) => {
    const requestData = activeRequests.get(details.requestId);
    if (requestData) {
      clearTimeout(requestData.timeoutTimer);
      activeRequests.delete(details.requestId);
      console.log(`请求成功: ${details.url},状态码: ${details.statusCode}`);
    }
  },
  { urls: ["<all_urls>"] },
  ["responseHeaders"]
);

// 请求出错时清理资源
chrome.webRequest.onErrorOccurred.addListener(
  (details) => {
    const requestData = activeRequests.get(details.requestId);
    if (requestData) {
      clearTimeout(requestData.timeoutTimer);
      activeRequests.delete(details.requestId);
      console.log(`请求失败: ${details.url},错误: ${details.error}`);
    }
  },
  { urls: ["<all_urls>"] }
);

额外优化:结合页面导航事件精准追踪

除了上面的方法,还可以监听页面导航/关闭事件,当页面刷新、跳转或关闭时,直接清理对应页面的所有活跃请求,标记为「页面操作导致取消」:

// 修改activeRequests存储结构,关联请求与tabId
const activeRequests = new Map();

// 在onBeforeRequest中记录tabId
chrome.webRequest.onBeforeRequest.addListener(
  (details) => {
    const requestId = details.requestId;
    const timeoutTimer = setTimeout(() => {
      if (activeRequests.has(requestId)) {
        console.log(`请求已取消/状态未知: ${details.url}`);
        activeRequests.delete(requestId);
      }
    }, 15000);
    
    activeRequests.set(requestId, {
      url: details.url,
      startTime: Date.now(),
      timeoutTimer,
      tabId: details.tabId
    });
  },
  { urls: ["<all_urls>"] },
  []
);

// 页面开始加载(导航)时清理对应tab的请求
chrome.tabs.onUpdated.addListener((tabId, changeInfo) => {
  if (changeInfo.status === "loading") {
    for (const [requestId, data] of activeRequests.entries()) {
      if (data.tabId === tabId) {
        clearTimeout(data.timeoutTimer);
        console.log(`页面导航取消请求: ${data.url}`);
        activeRequests.delete(requestId);
      }
    }
  }
});

// 页面关闭时清理对应tab的请求
chrome.tabs.onRemoved.addListener((tabId) => {
  for (const [requestId, data] of activeRequests.entries()) {
    if (data.tabId === tabId) {
      clearTimeout(data.timeoutTimer);
      console.log(`页面关闭取消请求: ${data.url}`);
      activeRequests.delete(requestId);
    }
  }
});

内容的提问来源于stack exchange,提问作者BNazaruk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 09:31:08