我可以阻止Chrome吃掉我的全球财产吗?

时间:2013-02-27 14:16:01

标签: javascript google-chrome chrome-ios

当您包含外部JavaScript文件时,iOS上的Chrome似乎会创建XMLHttpRequest对象。它似乎将此对象分配给标识符为a的全局变量,并覆盖您可能已经拥有的任何内容。

测试案例

  • HTML文件( test.html ):

    <!-- ... -->
    <script>
        var a = 1; // Value is not important for this demonstration
    </script>
    <script src="test.js"></script>
    <!-- ... -->
    
  • 外部JavaScript文件( test.js ):

    setTimeout(function () {
        document.write(a); // [object XMLHttpRequest]
        a.onreadystatechange = function () {
            document.write(a.readyState); // Alternates between "1" and "4"
        };
    }, 100);
    

XMLHttpRequest似乎重复发出请求(到某个地方......通过代理路由设备连接并且监视请求没有显示任何内容)并重复执行onreadystatechange事件处理程序

更多观察结果:

  • 这似乎只发生在页面加载后的某个时间(因此setTimeout
  • 当它发生时,还有一个window.__gchrome_CachedRequest属性
  • __gchrome_CachedRequest === a
  • 在旧版本的iOS Chrome中似乎没有发生(不知道它最初出现在哪个版本)

有没有人遇到过这个?有没有办法阻止它发生(注意......我不能重命名a)?如果有人知道为什么它会这样做,我很乐意找到。


更新

我刚刚注意到这实际上也发生在内联脚本中,而不仅仅是在包含外部脚本时。我最初没有注意到这一点,因为那里没有setTimeout电话。所以看起来它实际上只是总是在页面加载后的某个时间发生。

1 个答案:

答案 0 :(得分:2)

根据评论中的讨论,Chrome似乎正在使用with语句将一些自己的内容分层到window属性的顶部。它可能会这样做,因为这些属性通常不会被覆盖。延迟很可能取决于Chrome在页面开始加载后能够多快将自己的脚本注入UIWebView(iOS上的浏览器被迫使用底层UIWebView对象而不是自己的引擎)。

如果所有这些推测都是真的,那么除了访问window.a而不是a之外,还有一个简单的解决方案,或者取回电源并使用您自己的with语句:

with (window)
    eval(myScript);

几乎没有任何人愿意实施的解决方案,但可能是您唯一的选择。