chrome扩展-sendResponse不等待异步功能(chrome extension - sendResponse not waiting for async function)
描述:
1. content-script 1 中的 就是给 backgroun 发送了一个 message。(content-script 1 中的内容我就不贴出来了)
2. background 拿到 message 之后 会打开一个 新的标签页, 这个标签页会注入 content-script 2
3. content-script 2 收到消息后 要在异步中 sendMessage到 background 中。
问题:
最后一步 在setTimeout 中 sendMessage到 background 中时,拿不到message,同时 background 控制台还报如下错误。
Unchecked runtime.lastError: The message port closed before a response was received. 意思大致是:不受控制的运行时。lastError:在收到响应之前关闭的消息端口。没有拿到 response 想要 ,就关闭了这次通信。
background.js 监听 其它 content-script 1 发来的消息
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse){ console.log('这里是后台', request,'|||||||||||||', sender, '||||||||||||', sendResponse); if(request.message === 'autoReply'){ console.log('后台已经收到',request.data); sendResponse('我后台已收到'); // 打开一个新窗口 chrome.tabs.create({url: 'https://xxx.com/'}, tab => { console.log('新打开的 tab 信息', tab); if(!tab.id){ sendResponse({ state: 'rejected', message: '打开新窗口失败' }) return; } console.log('新tab id', tab.id); // 轮询 打开的新窗口 status 状态 let timer = setInterval(()=>{ chrome.tabs.get(tab.id, (tab)=>{ if(tab.status === 'complete'){ // 取消轮询 timer && clearTimeout(timer); console.log('页面加载完成了, 一秒后开始发送消息 到 content-script 2'); // 延迟1s 后给 新打开的 标签页 发送 message setTimeout(()=>{ chrome.tabs.sendMessage(tab.id, { message: request.message, data: request.data }, function(response){ // 一会主要看这里的打印情况 console.log('dongdong.js 的回复', response); }); }, 1000) } }); }, 1000); }); } });
content-script 2:
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse){ console.log('content-script 2 收到消息', request); if(request.message === 'autoReply'){ console.log('cs-dd.js 3秒后执行了自动回复') /* // 正常在这里写 sendResponse 是没有 会提的 background.js 会正常打印 response sendResponse({ message: "content-script 2 已经收到" }); */ setTimeout(()=>{ // 在这个异步 中进行 sendResponse 时候 background.js 打印的 response 为 undefined sendResponse({ message: "content-script 2 执行了自动回复" }); // do something .... // autoReply( request.data ); }, 3000) } // onMessage 返回 true 时候 sendResponse 就可以写在异步当中了 // return true; });
解决方法:
onMessage的回调应返回 true ,以保持内部消息通道开放,以便sendResponse可以异步工作。
调整后的 content-script 2
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse){ console.log('content-script 2 收到消息', request); if(request.message === 'autoReply'){ console.log('cs-dd.js 3秒后执行了自动回复') /* // 正常在这里写 sendResponse 是没有 会提的 background.js 会正常打印 response sendResponse({ message: "content-script 2 已经收到" }); */ setTimeout(()=>{ // 在这个异步 中进行 sendResponse 时候 background.js 打印的 response 为 undefined sendResponse({ message: "content-script 2 执行了自动回复" }); // do something .... // autoReply( request.data ); }, 3000) } // onMessage 返回 true 时候 sendResponse 就可以写在异步当中了 return true; });
当 return true; 时,在异步中 sendResponse 就可以成功到达 background 中。
参考:https://www.it1352.com/2107077.html