Chrome扩展注入脚本无法访问页面window全局变量如何解决
问题根因
chrome.scripting.executeScript默认注入的脚本运行在隔离执行上下文(Isolated World),和页面自身脚本的运行环境完全独立,二者的window对象不共享属性,因此直接访问window.code只能读取到隔离上下文内的变量,结果为undefined。
浏览器控制台默认在页面主上下文(Page World)执行代码,和页面自有脚本共享环境,因此可以直接读取到code变量的值。
修复方案
可根据兼容需求二选一:
方案1:直接指定注入脚本运行在页面主世界
Chrome 110及以上版本支持直接配置注入上下文,改造成本最低:
async function getCode() { let [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); chrome.scripting.executeScript({ target: { tabId: tab.id }, function: addCode, world: "MAIN" // 新增该配置,指定脚本在页面主上下文执行 }) } // 原有业务逻辑无需修改 function addCode() { const input = document.getElementById('some-id'); const btn = document.getElementById('some-id'); input.value = window.code; // 可正常读取到页面定义的code值 console.log(window.code); btn.click(); }
注意:使用该方案需要确保扩展的
manifest.json中已声明"scripting"权限,同时配置了对应站点的host_permissions。
方案2:动态插入script标签桥接(兼容低版本Chrome)
如果需要兼容Chrome 110以下版本,可以在注入脚本中动态创建script标签,将需要访问页面变量的逻辑放到标签内,插入页面后就会在主上下文执行:
function addCode() { const pageScript = document.createElement('script'); // 要在页面主上下文执行的逻辑直接写在textContent中 pageScript.textContent = ` const input = document.getElementById('some-id'); const btn = document.getElementById('some-id'); input.value = window.code; btn.click(); `; document.documentElement.appendChild(pageScript); // 执行完成后移除标签,避免冗余DOM pageScript.remove(); }
如果需要在主上下文和扩展隔离上下文之间传递数据,可以通过
window.postMessage实现通信,注意校验消息来源避免安全风险。
内容的提问来源于stack exchange,提问作者Code Eagle
相关产品推荐
相关产品推荐

