浏览器扩展:webRequest.onCompleted触发消息传递报错问题
问题分析与解决
错误根源
- 回调参数误用:
webRequest.onCompleted的回调接收的是请求详情对象(details),而非你定义的activeTab。你错误地从这个对象中读取tabId,当请求未关联有效标签页时(比如部分后台请求),details.tabId会返回-1,触发参数错误。 - 异步处理错误:
browser.tabs.query返回的是Promise对象,你直接赋值给activeTab但未处理异步结果,导致后续无法获取有效tab信息。 - 语法错误:
types参数的写法应为types: ['main_frame'],而非types['main_frame'],后者属于无效的对象语法。
修正后代码
manifest.json(无需修改)
{ "name": "shell", "manifest_version": 2, "version": "1.0", "background": {"scripts": ["background.js"]}, "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"] } ], "permissions": ["tabs","activeTab", "webRequest", "<all_urls>"] }
content.js(无需修改)
"use strict"; browser.runtime.onMessage.addListener((request) => { console.log("Message from the background script:"); console.log(request.greeting); return Promise.resolve({ response: "Hi from content script" }); });
修正后的background.js
function onError(error) { console.error("Error:", error); } // 从请求详情中获取tabId,仅向有效标签页发送消息 function sendMessageToTabs(details) { if (details.tabId !== -1) { browser.tabs.sendMessage(details.tabId, { greeting: "Hi from background script" }) .then((response) => { console.log("Message from the content script:"); console.log(response.response); }) .catch(onError); } } // 修正types参数语法,监听main_frame类型的请求完成事件 browser.webRequest.onCompleted.addListener( sendMessageToTabs, { urls: ["https://en.wikipedia.org/wiki/Vehicle"], types: ["main_frame"] } );
补充说明
如果需要向当前激活的标签页发送消息(而非请求对应的标签页),需正确处理tabs.query的异步结果:
// 向当前激活标签页发消息的正确写法 function sendToActiveTab() { browser.tabs.query({ currentWindow: true, active: true }) .then((tabs) => { if (tabs.length > 0) { browser.tabs.sendMessage(tabs[0].id, { greeting: "Hi from background script" }) .then(response => console.log(response.response)) .catch(onError); } }) .catch(onError); }
内容的提问来源于stack exchange,提问作者Ralf_Reddings
相关产品推荐
相关产品推荐

