zoukankan      html  css  js  c++  java
  • chrome插件访问原始页面的变量

    开发chrome插件时遇到需要获取原始网页中的一个js变量的值问题。由于content.js和原始网页的作用域环境不同,无法直接获取变量的值,提示undefined。谷歌找到大神提供的办法。综合起来记录如下:

    考虑到Google Reader的网页太复杂,这里就以Google首页来举例了。打开网页后,右键打开审查元素,然后在控制台输入fp,就会看到一个字符串,这就是原始网页的一个全局变量。

    现在我要获取它,就可以创建一个script元素,append到head。而这个script元素的执行环境是原始网页的,可以自由使用fp这个变量。
    不过fp取出来后也没法直接传递回content script。好在文档里说DOM是共用的,所以可以在这个script里,把值设置为某个元素的属性或innerText,再在content script里获取就行了:

    setTimeout(function() {
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.innerHTML = "document.body.setAttribute('data-fp', fp);";
        document.head.appendChild(script);
        document.head.removeChild(script);
    
        console.log(document.body.getAttribute('data-fp'));
    }, 1000);

    这里延迟的原因是原始网页加载完时,还需要等一会才会创建fp变量。

    另一种办法就是使用location.href,它是用来跳转网页的,但是也可以用来执行JavaScript,并且执行环境也是原始网页:

    setTimeout(function() {
        location.href = "javascript:document.body.setAttribute('data-fp', fp);";
        setTimeout(function() {
            console.log(document.body.getAttribute('data-fp'));
        }, 0);
    }, 1000);

    这里嵌套使用了setTimeout,原因是跳转是一个事件,并不会打断当前脚本的执行(而添加script元素会立刻执行),因此需要让后面的语句等待事件处理完毕。

    不过前面所说的方法都必须先保存,再取出,能这样做的只有字符串等简单类型,对函数则无能为力了。
    实际上还有更方便的方法,那就是在DOM上绑定一个事件,而事件的处理函数则返回window变量,再在程序中触发这个事件,就能获得执行环境的window变量了。幸运的是,这个执行环境仍然是原始网页的:

    setTimeout(function() {
        var div = document.createElement('div');
        div.setAttribute('onclick', 'return window;');
        var unsafeWindow = div.onclick();
        console.log(unsafeWindow.fp);
    }, 1000);
  • 相关阅读:
    Basic GC Tuning
    程序员如何少走弯路,更好的提升技术。
    WPF 多线程
    IOC
    一句话概括WPF知识点
    WPF数据绑定 Binding
    WPF命令
    WPF依赖属性
    WPF路由事件
    WPF绘图和动画
  • 原文地址:https://www.cnblogs.com/parker-yu/p/9046463.html
Copyright © 2011-2022 走看看