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

Chrome扩展:后台脚本向内容脚本发消息报错求助

解决Chrome扩展Background与Content Script消息通信的错误问题

我来帮你排查这两个错误的原因并给出修复方案:

错误原因拆解

  1. "Could not establish connection. Receiving end does not exist."
    这个错误核心是:当background script尝试给目标tab发消息时,该tab里并没有加载你的content script。常见场景包括:
    • 你右键操作的是Chrome内部页面(比如chrome://extensions/、chrome://settings/),这类页面不在<all_urls>的匹配范围内,content script不会自动注入
    • 目标tab刚打开,content script还没完成注入就触发了消息发送
  2. "TypeError: Cannot read property 'getSelected' of undefined"
    这是连锁错误:因为第一个通信失败问题,sendMessage回调里的response是undefined,你调用response.getSelected()自然会抛出类型错误。

修复后的完整代码示例

1. 更新background_script.js

添加错误处理逻辑,同时支持动态注入content script,确保接收端存在:

// 先初始化右键菜单(之前可能遗漏了这一步)
chrome.runtime.onInstalled.addListener(function() {
  chrome.contextMenus.create({
    id: "fetchSelectedText",
    title: "获取选中文本",
    contexts: ["selection"] // 只在有文本选中时显示菜单,更合理
  });
});

chrome.contextMenus.onClicked.addListener(function(info, tab){
  // 过滤Chrome内部页面和扩展自身页面,这些页面无法注入普通content script
  const forbiddenPrefixes = ['chrome://', 'chrome-extension://'];
  const isForbidden = forbiddenPrefixes.some(prefix => tab.url.startsWith(prefix));
  
  if(isForbidden){
    console.log("无法在Chrome内部/扩展页面执行此操作");
    return;
  }

  // 尝试发送消息,同时处理通信错误
  chrome.tabs.sendMessage(tab.id, { content: "getSelected" }, function(response) {
    if(chrome.runtime.lastError){
      console.log("通信失败,尝试动态注入content script:", chrome.runtime.lastError.message);
      // 动态注入content script后再次发送消息
      chrome.tabs.executeScript(tab.id, {file: 'content_script.js'}, function(){
        chrome.tabs.sendMessage(tab.id, { content: "getSelected" }, function(response) {
          if(response?.getSelected){
            console.log("选中的内容:", response.getSelected);
          }
        });
      });
    } else if(response?.getSelected){
      console.log("选中的内容:", response.getSelected);
    }
  });
});

2. 完善content_script.js

补充缺失的getSelected函数定义,确保能正确返回选中内容:

// 定义获取选中文本的核心函数
function getSelected(){
  return window.getSelection().toString().trim();
}

chrome.runtime.onMessage.addListener(function(message, sender, sendResponse) {
  if (message.content === "getSelected") {
    sendResponse({getSelected: getSelected()});
  }
  // 注:如果后续涉及异步操作,需要在这里返回true告知Chrome等待异步响应
});

3. manifest.json(保持原有配置即可,无需额外修改)

{
  "manifest_version": 2,
  "content_scripts":[
    {
      "matches": ["<all_urls>"],
      "js": ["content_script.js"]
    }
  ],
  "background":{
    "scripts": ["background_script.js"]
  },
  "permissions": [
    "*://*/*",
    "activeTab",
    "declarativeContent",
    "storage",
    "contextMenus",
    "tabs"
  ]
}

关键注意事项

  • 永远在sendMessage的回调里检查chrome.runtime.lastError,这是处理扩展通信失败的标准做法
  • Chrome内部页面和扩展自身页面无法注入普通content script,必须提前过滤
  • 确保content script里的所有依赖函数都已正确定义,避免因函数缺失导致响应异常

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 09:32:52