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

Chrome扩展开发:AJAX加载对象在监听器调用中报错未定义

解决Chrome扩展中“无法读取undefined的banned属性”问题

这个错误的核心原因是异步请求的时序问题,我来给你一步步拆解和解决:

为什么会报错?

你用XMLHttpRequest发起的是异步请求,这意味着调用xhttp.send()之后,代码不会停下来等待banned.json的响应返回,而是直接继续执行后面的chrome.webNavigation.onCompleted.addListener语句。

此时obj还是你一开始声明的空变量(undefined),自然就会抛出“无法读取undefined的banned属性”的错误——虽然你在请求成功的回调里给obj赋值了,但这个回调是在请求完成后才会执行,晚于添加监听器的代码。

修复方案:把监听器逻辑移到请求成功的回调里

我们需要确保只有当banned.json加载完成并解析后,再去添加webNavigation的监听器。同时还要注意,chrome.webNavigation.onCompleted.addListener的第二个参数是过滤条件对象,不是直接传关键词数组,需要转换成符合要求的格式。

修改后的background.js代码如下:

var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function(){
  if(xhttp.readyState == 4 && xhttp.status == 200){
    const obj = JSON.parse(xhttp.response);
    console.log(obj.banned);
    
    // 构造webNavigation的过滤规则:匹配URL包含任意禁用关键词的主框架请求
    const filter = {
      url: obj.banned.map(keyword => ({ urlContains: keyword }))
    };
    
    // 现在obj.banned已正确加载,在这里添加监听器
    chrome.webNavigation.onCompleted.addListener(closeTab, filter);
  }
};
xhttp.open('GET', "banned.json", true);
xhttp.send();

function closeTab(e) {
  if (!e.frameId) { // 只处理页面主框架的加载完成事件,避免iframe触发
    console.log("关闭标签页ID:", e.tabId);
    chrome.tabs.remove(e.tabId);
  }
}

额外注意事项

  1. 权限声明:确保你的manifest.json中声明了必要的权限,否则扩展会无法正常工作:
{
  "manifest_version": 3, // 如果你用的是V3版本,V2配置逻辑类似
  "name": "你的扩展名称",
  "version": "1.0",
  "background": {
    "service_worker": "background.js" // V3用service_worker,V2用scripts字段
  },
  "permissions": ["webNavigation", "tabs"]
}
  1. 匹配规则调整:如果你的禁用关键词是完整URL(比如https://www.google.de/),可以把urlContains换成urlEquals,这样匹配更精准;如果是域名(比如youtube.com),urlContains就足够覆盖该域名下的所有页面。

内容的提问来源于stack exchange,提问作者Mr.X

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:51:36