Chrome扩展content script触发关非活动标签时thisTab.id为undefined问题
问题根因
两个触发场景给回调函数传的参数结构完全不一样,直接照搬点击扩展图标的参数处理逻辑,自然拿不到正确的标签页ID:
- 绑定在
chrome.browserAction.onClicked上的监听器,回调的第一个参数本身就是当前活动标签页的Tab对象,所以直接读.id能拿到有效值,逻辑运行正常。 chrome.runtime.onMessage的监听器回调参数根本不是Tab对象,它的固定参数顺序是(消息内容, 消息发送者信息, 响应回调):- 第一个参数是content script主动发过来的消息体,你content script里发的是空对象
{},这个对象上根本没有id属性 - 第二个参数
sender才是携带消息来源上下文的对象,发送这条消息的标签页ID存在sender.tab.id字段里
你现在把第一个空消息对象当成Tab对象传入关闭函数,读id得到undefined,判断条件tab.id !== undefined对所有标签页都成立,自然会把所有标签页全部关掉。
- 第一个参数是content script主动发过来的消息体,你content script里发的是空对象
修复方法
调整background.js里的消息监听逻辑,从sender参数里取来源标签页ID,不要把消息体误当Tab对象传入:
const closeAllTabs = function(keepTabId) { chrome.tabs.query({}, function(tabs){ for (let tab of tabs) { if (tab.id !== keepTabId) { chrome.tabs.remove(tab.id); } } }); } // 保留原扩展图标点击触发逻辑 chrome.browserAction.onClicked.addListener(function(activeTab) { closeAllTabs(activeTab.id); }); // 修正消息监听逻辑 chrome.runtime.onMessage.addListener(function(message, sender) { // 校验来源是标签页再执行,避免异常场景报错 if (sender.tab?.id) { closeAllTabs(sender.tab.id); } });
额外注意配置问题:你现在content script配置了all_frames: true,页面内所有iframe加载完成时都会发一次消息,会重复触发关闭逻辑,建议把这个配置改成false,只让页面主框架加载完成时发一次消息,避免重复执行。
内容的提问来源于stack exchange,提问作者Vladislav moroz
相关产品推荐
相关产品推荐

