浏览器插件消息通信:异步机制与数据获取避坑(ps:发送方收到的返回值是 undefined)
一、核心结论
chrome.runtime.sendMessage(以及旧版chrome.extension.sendMessage)是完全异步的。- 接收方(
onMessage)若包含耗时或异步操作,必须显式返回true,否则发送方会立刻收到undefined。 - 发送方获取返回数据推荐使用
async/await或Promise写法,代码更简洁直观。
二、发送方:消息发送与数据获取
发送方通过
sendMessage 发出请求,并通过回调、Promise 或 await 接收接收方返回的数据。chrome.runtime.sendMessage({ type: 'zhousavedata', data: '测试数据' }, (response) => {
// response 即为接收方返回的数据
console.log("获取到返回数据:", response);
});
2. Promise 写法(现代)
chrome.runtime.sendMessage({ type: 'zhousavedata', data: '测试数据' })
.then((response) => {
console.log("通过 Promise 获取到的数据:", response);
})
.catch((error) => {
console.error("消息发送失败:", error);
});
3. async/await 写法(强烈推荐,最简洁)
async function sendData() { try { // 像写同步代码一样等待异步返回的结果 const response = await chrome.runtime.sendMessage({ type: 'zhousavedata', data: '测试数据' }); console.log("通过 await 获取到的数据:", response); } catch (error) { console.error("消息发送失败:", error); } } sendData();
三、接收方:异步处理与响应通道
接收方通过
onMessage 监听消息。如果监听器内部包含异步操作(如 setTimeout、fetch、chrome.storage 等),必须保持消息通道打开。1. 错误写法(通道被提前关闭)
如果不返回
如果不返回
true,监听器函数执行完毕后 Chrome 会立刻关闭通道。后续异步操作完成时调用 sendResponse 将失效,发送方会立刻收到 undefined
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.type === 'zhousavedata') { setTimeout(() => { // 此时通道已关闭,发送方收不到此数据 sendResponse({ status: 'success', msg: '保存成功' }); }, 1000); // ️ 缺少 return true } });
2. 正确写法(显式返回 true)
通过 return true 明确告知 Chrome 这是一个异步响应,请保持通道打开,等待后续的 sendResponse。
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.type === 'zhousavedata') { setTimeout(() => { sendResponse({ status: 'success', msg: '保存成功' }); }, 1000); // 关键:返回 true,声明这是一个异步响应 return true; } });
3. 最佳实践(直接返回 Promise)
直接返回一个 Promise,Chrome 会自动保持通道打开,并在 Promise resolve 时将结果发回给发送方。无需手动调用 sendResponse 和 return true。
chrome.runtime.onMessage.addListener((request, sender) => { if (request.type === 'zhousavedata') { // 直接返回 Promise,resolve 的内容即为发送给请求方的数据 return new Promise((resolve) => { setTimeout(() => { resolve({ status: 'success', msg: 'Promise 异步处理完毕' }); }, 1000); }); } });
四、常见问题排查清单
- 发送方收到
undefined:检查接收方是否在异步操作外忘记写return true,或者sendResponse被提前调用。 - 数据无法传递:检查
sendResponse或resolve传递的数据是否包含不可序列化的对象(如 DOM 节点、函数、循环引用等)。 - API 规范:现代 Chrome 插件开发中,官方推荐使用
chrome.runtime.sendMessage替代较老的chrome.extension.sendMessage。

浙公网安备 33010602011771号