如何将addEventListener存储的数据从foreground.js传回background.js
问题排查
核心问题原因
addEventListener本身无返回值:你代码中data = pswdBtns[i].addEventListener(...)的写法是错误的,addEventListener仅负责绑定事件回调,返回值为undefined,不可能拿到点击事件触发后生成的业务数据。且点击事件是异步触发的,注入脚本执行时仅完成事件绑定,此时用户还未点击按钮,不存在你需要的data数据。chrome.tabs.executeScript回调的取值逻辑错误:该API的回调参数仅能拿到注入脚本同步执行的最后一个表达式返回值,你的foreground.js同步执行到最后输出console.log("End"),返回值为undefined,所以background中打印的data自然是空值。你需要的点击后产生的数据属于注入完成后异步生成的内容,无法通过该回调获取。- 元素绑定逻辑存在缺陷:初始化时
pswdBtns是空数组,循环仅会执行i=0一次,且edge://settings/passwords的密码列表是动态渲染的,脚本注入时列表可能还未加载完成,大概率找不到对应元素导致事件绑定失败。 - background中的while循环逻辑冗余:你定义的
pswdPageChecked变量仅会自增一次,循环只会执行1次,完全没有存在的必要。
解决方案
通过Chrome扩展的跨上下文消息通信机制实现数据传输:点击事件触发后,由foreground主动向background发送携带数据的消息,background监听消息接收即可。同时修复元素绑定逻辑。
修改后的 foreground.js
console.log("foreground.js injected"); function readUUID(){ var navigator_info = window.navigator; var screen_info = window.screen; var uid = navigator_info.mimeTypes.length; uid += navigator_info.userAgent.replace(/\D+/g, ''); uid += navigator_info.plugins.length; uid += screen_info.height || ''; uid += screen_info.width || ''; uid += screen_info.pixelDepth || ''; return uid; } async function passwordProtected(pointerList){ const date = new Date(); const uid = readUUID(); alert("You are in dangerous on \'"+ pointerList.title + "' row = " + pointerList.id.slice(20)); const data = { "Webtitle": pointerList.href, "Title": pointerList.title, "Time": date.toString(), "UUID": uid } console.log("foreground 生成数据:", data); // 新增:主动发消息给background chrome.runtime.sendMessage(data, (response) => { console.log("数据发送完成", response); }); } // 新增:监听页面动态渲染的密码列表,避免找不到元素 function bindEvents() { let i = 0; while(true) { const btn = document.querySelector("#passwordShowPasswordButton_"+ i); const link = document.querySelector("#passwordWebsitelink_"+ i); if(!btn || !link) break; btn.addEventListener('click', passwordProtected.bind(btn, link)); console.log(link.title, link.href); i++; } if(i === 0) { // 列表还没渲染,1秒后重试 setTimeout(bindEvents, 1000); } } // 页面加载完成后执行绑定 if(document.readyState === "complete" || document.readyState === "interactive") { bindEvents(); } else { window.addEventListener("DOMContentLoaded", bindEvents); } console.log("foreground 初始化完成");
修改后的 background.js
注:如果是Manifest V3版本扩展,请将
chrome.tabs.executeScript替换为chrome.scripting.executeScript相关API,同时需要在manifest中声明scripting权限。
const edgePswd = "edge://settings/passwords"; chrome.tabs.onActivated.addListener(async (tab) => { const current_tab_info = await chrome.tabs.get(tab.tabId); if (current_tab_info.url === edgePswd) { chrome.tabs.executeScript(null, { file: "/extension/foreground.js" }, () => { console.log("foreground 注入完成"); }); } }); // 新增:监听foreground发送的消息 chrome.runtime.onMessage.addListener((data, sender, sendResponse) => { console.log("收到foreground传来的数据:", data); // 这里可以写你拿到数据后的业务逻辑 sendResponse("接收成功"); });
额外权限配置
需要在manifest.json中添加消息通信相关的权限配置,确保跨上下文通信正常:
// Manifest V2 新增配置 "permissions": ["tabs", "http://*/*", "https://*/*", "edge://settings/*"]
// Manifest V3 新增配置 "permissions": ["tabs", "scripting"], "host_permissions": ["edge://settings/*"]
内容的提问来源于stack exchange,提问作者テンカサン
相关产品推荐
相关产品推荐

