Chrome扩展:getAuthToken回调中调用sendResponse无效的解决办法
解决Chrome扩展中异步回调调用sendResponse失效的问题
这个坑我之前踩过!你遇到的问题核心在于Chrome的消息传递机制规则:默认情况下,chrome.runtime.onMessage(注意现在官方更推荐用这个替代chrome.extension.onMessage)的监听函数执行完毕后,sendResponse就会被销毁,而chrome.identity.getAuthToken是异步操作,它的回调触发时,原监听函数早就跑完了,所以调用sendResponse自然没用。
下面给你两种靠谱的解决方案:
方案一:返回true保持消息通道开放
这是最直接的修复方式,只要在监听函数里返回true,就能告诉Chrome:“我要等异步操作完成后再返回结果,别着急关闭消息通道”。修改后的代码如下:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) { if (request.task == "auth") { chrome.identity.getAuthToken({ 'interactive': true }, function(token) { if (chrome.runtime.lastError) { // 把错误信息返回给弹窗 sendResponse({ error: chrome.runtime.lastError.message }); return; } // 成功拿到token后返回 sendResponse({ token: token }); }); // 关键!返回true,维持消息通道的存活 return true; } });
方案二:用Promise+async/await(更现代的写法)
现在Chrome已经支持onMessage的监听函数返回Promise,这种写法不用手动管理sendResponse,代码更简洁易读:
chrome.runtime.onMessage.addListener(async function(request, sender) { if (request.task == "auth") { try { // 把getAuthToken包装成Promise const token = await new Promise((resolve, reject) => { chrome.identity.getAuthToken({ 'interactive': true }, function(token) { if (chrome.runtime.lastError) { reject(chrome.runtime.lastError.message); return; } resolve(token); }); }); // 返回token给弹窗 return { token: token }; } catch (error) { // 返回错误信息 return { error: error }; } } });
弹窗脚本的对应处理
不管用哪种方案,弹窗那边的sendMessage都要处理返回的结果,比如:
// 弹窗脚本代码 chrome.runtime.sendMessage({ task: "auth" }, function(response) { if (response.error) { alert(`授权失败:${response.error}`); return; } console.log("成功获取token:", response.token); // 这里写拿到token后的业务逻辑 });
内容的提问来源于stack exchange,提问作者Richard Bernstein
相关产品推荐
相关产品推荐

