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

Chrome扩展service worker与popup.js通信报Receiving end不存在错误如何解决

解决方案

错误根因

Chrome 扩展的 popup 是临时运行上下文,仅当用户点击扩展图标、popup 处于打开状态时,popup.js 才会加载运行,你写的 onConnect 监听才会生效。如果 popup 未打开、或已经被关闭,service worker 主动发起连接时自然找不到接收端,就会抛出这个错误。

调整方案

你可以根据自己的需求选择以下任意一种或组合使用:

方案1:增加错误捕获,避免异常抛出

如果允许popup未打开时丢失消息,只需要在service worker侧增加错误判断和捕获逻辑即可:

function inputController() {
  var store, remainingSessions, request, port;
  store = getObjectStore("readonly");
  request = store.getAll();
  request.onsuccess = function () {
    remainingSessions = request.result;
    try {
      port = chrome.runtime.connect({ name: "RemainingSessions" });
      // 捕获连接错误
      if (chrome.runtime.lastError) {
        console.log("Popup未处于打开状态,消息发送失败");
        return;
      }
      port.postMessage(remainingSessions);
      // 监听连接断开事件
      port.onDisconnect.addListener(() => {
        if (chrome.runtime.lastError) {
          console.log("连接已断开");
        }
      });
    } catch (e) {
      console.log("消息发送异常", e);
    }
  };
}

方案2:用storage做数据中转,保证消息不丢失

如果需要保证登出事件的通知不会因为popup未打开而丢失,优先用chrome.storage.local做数据兜底,popup打开后主动拉取数据:

service worker 侧调整

function inputController() {
  var store, remainingSessions, request, port;
  store = getObjectStore("readonly");
  request = store.getAll();
  request.onsuccess = function () {
    remainingSessions = request.result;
    // 先把数据写入本地存储兜底
    chrome.storage.local.set({ remainingSessions }, () => {
      // 再尝试向popup发消息,能连上就实时同步
      try {
        port = chrome.runtime.connect({ name: "RemainingSessions" });
        if (!chrome.runtime.lastError) {
          port.postMessage(remainingSessions);
        }
      } catch(e) {}
    });
  };
}

popup.js 侧调整

// 初始化时主动拉取存储的历史数据
document.addEventListener('DOMContentLoaded', async () => {
  const { remainingSessions } = await chrome.storage.local.get('remainingSessions');
  if (remainingSessions) {
    console.log("获取到会话数据", remainingSessions);
    // 在此处执行你的页面渲染逻辑
  }
});

// 监听存储变化,实时更新数据
chrome.storage.onChanged.addListener((changes, area) => {
  if (area === 'local' && changes.remainingSessions) {
    const newSessions = changes.remainingSessions.newValue;
    console.log("会话数据更新", newSessions);
    // 在此处执行你的页面更新逻辑
  }
});

// 原有长连接监听可保留,用于实时通信
chrome.runtime.onConnect.addListener(function (port) {
  port.onMessage.addListener(function (remainingSessions) {
    console.assert(port.name === "RemainingSessions");
    console.log("收到实时消息 " + remainingSessions);
  });
});

方案3:改为popup主动发起长连接

如果需要维持稳定的长连接,改为生命周期更短的popup主动向service worker发起连接,service worker保存连接实例后再发消息:

popup.js 侧调整

// popup初始化时主动发起连接
const port = chrome.runtime.connect({ name: "RemainingSessions" });
port.onMessage.addListener((remainingSessions) => {
  console.assert(port.name === "RemainingSessions");
  console.log("Message received " + remainingSessions);
});

service worker 侧调整

// 保存popup的连接实例
let popupPort = null;
chrome.runtime.onConnect.addListener((port) => {
  if (port.name === "RemainingSessions") {
    popupPort = port;
    // 连接断开时清空实例
    port.onDisconnect.addListener(() => {
      popupPort = null;
    });
  }
});

function inputController() {
  var store, remainingSessions, request;
  store = getObjectStore("readonly");
  request = store.getAll();
  request.onsuccess = function () {
    remainingSessions = request.result;
    // 优先写入存储兜底
    chrome.storage.local.set({ remainingSessions });
    // 存在活跃连接时才发消息
    if (popupPort) {
      try {
        popupPort.postMessage(remainingSessions);
      } catch (e) {
        popupPort = null;
      }
    }
  };
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 13:15:07