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
相关产品推荐
相关产品推荐

