Chrome MV3中await sendMessage获取后台响应返回undefined问题排查
问题原因与解决方案
这是代码问题,核心是Chrome MV3环境下,Service Worker中chrome.runtime.onMessage监听器的异步响应处理不符合规范,导致popup提前收到undefined。
具体原因
你当前通过返回Promise的方式做异步响应,但在MV3的Service Worker事件模型中,这种方式无法让Chrome正确等待异步操作完成:当监听器函数执行完毕后,Chrome会默认认为没有异步响应,直接给popup返回undefined,而后台的fetch操作此时还在进行,所以会出现popup先打印response called undefined,之后后台才输出json called {...}的情况。
另外你的catch块没有返回被rejected的Promise,一旦请求出错也会导致响应为undefined,不过当前请求成功仍出现问题,所以核心还是异步响应的处理方式问题。
修复方案
使用sendResponse回调函数,并在监听器中返回true,明确告知Chrome需要等待异步操作完成:
修改后的background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { fetch('https://example.com/') .then(response => response.json()) .then(response => { console.log('json called', response); sendResponse(response); }) .catch(error => { console.log('error called', error); sendResponse(error); }); return true; // 关键:通知Chrome等待异步响应 });
或者用async/await写法:
chrome.runtime.onMessage.addListener(async (message, sender, sendResponse) => { try { const response = await fetch('https://example.com/'); const data = await response.json(); console.log('json called', data); sendResponse(data); } catch (error) { console.log('error called', error); sendResponse(error); } return true; });
修改后popup就能正确等待后台的异步响应,不会再提前收到undefined。
内容的提问来源于stack exchange,提问作者erosman
相关产品推荐
相关产品推荐

