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

Chrome扩展新标签页首次加载时内容脚本无法接收后台消息

Chrome扩展新标签页跳转时内容脚本收不到消息的问题解决

问题本质

在新标签页输入URL跳转时,内容脚本加载后立即发送初始化消息,但此时Chrome的sender.tab信息仍停留在chrome://newtab/(tab URL存在更新延迟)。后台基于这个旧的tab信息发送CHANGE_BG消息时,消息会被投递到已处于卸载状态的newtab页面,而非当前加载的目标页面,导致内容脚本无法接收。

解决方案

方案1:后台监听页面加载完成后再发消息

后台不直接在收到内容脚本消息后回发,而是先记录待处理的tab,等页面加载完成且URL匹配后再发送消息:

// background script
const pendingTabs = new Set();

chrome.runtime.onMessage.addListener((message, sender) => {
  if (message.action === "NOTIFY_CONTENT_SCRIPT_LOADED") {
    console.log(`### ACK content script in page: ${message.pageURL} and tab: ${sender.tab.url}`);
    // 记录tab和目标URL
    pendingTabs.add({
      tabId: sender.tab.id,
      targetUrl: message.pageURL
    });
  }
});

chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
  // 仅处理已加载完成且匹配目标URL的tab
  if (changeInfo.status === 'complete' && tab.url) {
    const pendingItem = Array.from(pendingTabs).find(item => item.tabId === tabId && item.targetUrl === tab.url);
    if (pendingItem) {
      chrome.tabs.sendMessage(tabId, { action: "CHANGE_BG" }, () => {
        console.log("### ACK changed BG color of client page");
        pendingTabs.delete(pendingItem);
      });
    }
  }
});

方案2:内容脚本等待页面加载完成后再发初始化消息

延迟发送消息,确保tab的URL已更新,后台能拿到正确的tab信息:

// content script
chrome.runtime.onMessage.addListener((message, _, sendResponse) => {
  if (message.action === "CHANGE_BG") {
    document.body.style.background = "yellow";
    sendResponse();
  }
});

// 等待页面完全加载后发送初始化消息
window.addEventListener('load', () => {
  console.log("### Notifying background from page: " + location.href);
  chrome.runtime.sendMessage({ action: "NOTIFY_CONTENT_SCRIPT_LOADED", pageURL: location.href });
});

方案3:后台查询最新tab信息再发消息

收到内容脚本消息后,先获取该tab的最新状态,确认URL匹配后再发送消息:

// background script
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.action === "NOTIFY_CONTENT_SCRIPT_LOADED") {
    console.log(`### ACK content script in page: ${message.pageURL} and tab: ${sender.tab.url}`);
    
    // 查询tab最新信息
    chrome.tabs.get(sender.tab.id, (tab) => {
      if (tab.url === message.pageURL) {
        chrome.tabs.sendMessage(sender.tab.id, { action: "CHANGE_BG" }, () => {
          console.log("### ACK changed BG color of client page");
        });
      }
    });
    sendResponse(); // 必须调用避免内存泄漏
  }
});

关于chrome.runtime.connect断开的补充

页面跳转时,旧newtab页面的内容脚本被销毁,对应端口会断开。新页面的内容脚本会重新建立连接,后台可以在onConnect事件中记录tab的最新状态,或等待页面加载完成后再通过端口通信。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 04:43:26