返回true仍触发Message port closed报错,Chrome扩展消息通信问题
Chrome扩展消息通信异步响应报错
我在Chrome扩展中从popup页面向background发送消息,background接收后调用外部API,获取响应后再向popup返回消息,但一直收到错误提示。
Popup代码
chrome.runtime.sendMessage({ message: "submit", payload: { transactions: usersTxs, } }, (response) => { ... do other stuff });
Background代码(原错误版本)
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.message === 'submit'){ fetch('https://example.com/api/submit') .then((res) => { sendResponse({ message: true }) return true }) } });
报错信息
Unchecked runtime.lastError: The message port closed before a response was received
Uncaught (in promise) Error: A listener indicated an asynchronous response by returning true, but the message channel closed before a response was received
问题原因与修正
核心错误是**return true的位置不对**:
Chrome要求,当onMessage的监听器需要异步发送响应时,必须立刻在监听器函数的顶层返回true,以此告知Chrome要保留消息端口,等待异步响应。你现在把return true放在了fetch的then回调里,这相当于监听器函数本身没有返回值(默认返回undefined),Chrome会认为响应已经发送,直接关闭消息端口,等到后续调用sendResponse时就会报错。
修正后的Background代码
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.message === 'submit'){ fetch('https://example.com/api/submit') .then((res) => { sendResponse({ message: true }); }); // 关键:在监听器顶层返回true,告知Chrome等待异步响应 return true; } });
额外建议:添加错误处理
为了避免API请求失败时sendResponse未被调用导致的类似错误,建议补充catch捕获异常:
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.message === 'submit'){ fetch('https://example.com/api/submit') .then((res) => { if (!res.ok) throw new Error(`请求失败:${res.status}`); return res.json(); // 若需要解析响应体可添加 }) .then((data) => { sendResponse({ message: true, data }); }) .catch((err) => { sendResponse({ message: false, error: err.message }); }); return true; } });
内容的提问来源于stack exchange,提问作者TC23
相关产品推荐
相关产品推荐

