7

XMLHttpRequest当您包含外部 JavaScript 文件时,iOS 上的 Chrome 似乎会创建一个对象。似乎将此对象分配给具有标识符的全局变量,从而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在那里打电话。所以看起来它实际上总是在页面加载后的某个时间发生。

4

1 回答 1

2

从我们在评论中的讨论来看,Chrome 似乎正在使用一个with声明来将它自己的一些东西放在window属性的顶部。它可能会这样做,因为这些属性通常不会被覆盖。延迟很可能归结为在页面开始加载后 Chrome 可以多快将自己的脚本注入 UIWebView(iOS 上的浏览​​器被迫使用底层 UIWebView 对象而不是它们自己的引擎)。

如果所有这些猜测都是真的,那么有一个简单的解决方案,除了访问window.a而不是a或收回权力并使用你自己的with声明:

with (window)
    eval(myScript);

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

于 2013-02-27T15:04:58.780 回答