开发Chrome扩展时如何获取<script>标签内部定义的JS变量?
你现在拿不到目标变量的核心逻辑很简单:通过document.getElementById('myscript')拿到的只是DOM层面的<script>标签节点,标签内部用const在脚本顶层声明的变量,既不会挂载到全局window对象上,也和Chrome扩展内容脚本的隔离作用域完全隔开,单纯操作DOM节点的属性是取不到运行时的变量值的。
不同场景的对应解决方法
场景1:控制台切换到页面原生执行上下文操作(控制台顶部上下文选择器选当前页面域名,而非你的扩展)
这是最省事的情况:
- 完全不需要绕路读标签文本,直接在控制台输入
data就能拿到对应值。同一页面内的原生脚本共享全局词法环境,顶层声明的const变量虽然不绑定为window的属性,但同上下文下可以直接访问。 - 如果遇到变量被作用域遮蔽,无法直接访问的情况,再从标签文本提取:直接读取script标签的代码文本,匹配出
data对应的表达式再解析即可,示例代码:// 获取script标签内的完整代码文本 const scriptContent = document.getElementById('myscript').textContent; // 提取data对应的赋值表达式 const dataLiteral = scriptContent.match(/const data = (.*);/s)[1]; // 解析为实际JS对象 const targetData = eval(`(${dataLiteral})`);
场景2:在Chrome扩展的隔离执行上下文运行(即content script代码、控制台切到扩展上下文时)
受扩展的隔离世界机制限制,直接访问data会抛出未定义错误,这时候可以用两种无侵入方案实现取值:
- 方案1:通过共享的DOM读取文本做解析。DOM是隔离世界和页面完全共享的,你可以直接拿到script标签的完整文本,用正则匹配出
data对应的JSON字符串再反序列化。这种方法不会触发页面的CSP限制,因为不需要执行任何页面内的脚本:const scriptText = document.getElementById('myscript').textContent; // 正则兼容换行、多余空格的写法 const dataJsonStr = scriptText.match(/const data\s*=\s*([\s\S]*?);\s*$/)[1]; const targetData = JSON.parse(dataJsonStr); - 方案2:临时注入页面内脚本做跨上下文传值。如果script里的变量不是纯JSON结构、正则无法完整解析,可以创建一段临时的内联脚本,把变量值序列化后存在DOM的自定义属性上,等脚本执行完成后,再回到扩展上下文从DOM上把值读回来解析。
常见踩坑提醒:不要尝试写
window.data来取值。代码里用const声明的变量根本不会成为window对象的属性,只有用var声明、或者直接给window赋值的变量,才能在window上查到。
内容的提问来源于stack exchange,提问作者abdullahDev
相关产品推荐
相关产品推荐

