【问题标题】:Intercepting AJAX requests on Chrome for iOS?在 Chrome for iOS 上拦截 AJAX 请求?
【发布时间】:2015-06-01 08:22:08
【问题描述】:

我通过更改 XMLHttpRequest.prototype opensend 方法在我的站点中拦截 AJAX 请求。这种方法在我测试的所有浏览器中都没有任何问题。然而,对于 iOS 版 Chrome (iPhone),代码有一个最奇怪的错误:就像它不断触发我在原型中更改的代码(显然最终崩溃了)。

这是我正在做的一个超级最小的例子:

var open = XMLHttpRequest.prototype.open; // Caching the original
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
    alert('open'); // Here is my code
    open.call(this, method, url, async, user, pass); // Calling the original
 };

我已经组装了一个小 JSBin,您可以在 iOS 上使用 Chrome 访问:Demo

根据this 的答案,我正在使用的代码(基本上与该答案中将使用的一个 OP 相同)是安全的,没有理由担心。而且,事实上,iOS 版 Chrome 是唯一表现异常的浏览器。

这两天让我发疯了,感谢任何建议或解决方法。

【问题讨论】:

  • XMLHttpRequest.prototype.open = function() { alert("moo"); open.apply(this, arguments); } 会发生什么? call 不将操作上下文作为第一个参数,而是将其视为第一个函数参数。但是,appy 确实如此。
  • 据我所知call does take the operation context as the first argument,唯一的区别在于其余的论点。但是,无论如何,我尝试使用apply 对其进行编辑,但我得到了同样的错误。平心而论,我试图完全删除该行,但我仍然遇到同样的问题:似乎编辑 XMLHttpRequestsprototype 可以做到这一点。
  • 好点。其他 IOS 浏览器能用吗?因为 IOS 上的所有浏览器本质上都是同一个渲染引擎之上的“可用性接口”。还有,是不是特定版本的IOS?
  • 是的,我尝试了其他 iOS 浏览器,例如 Mercury 和 Opera Mini。我听说 iOS 版 Chrome 的怪癖远远超出了您对 WebView 的期望。我的 iOS 版本是 8.2,但我已经尝试在 iOS 7 上使用朋友的 iPhone。 Chrome 版本最新于:41.0.2272.58。
  • 您的 JSBin 似乎没有调用 open 函数。您能否确认您是否遇到this bin 的问题?如果是这样,您是否也有this bin 的问题?

标签: javascript ios ajax chrome-ios


【解决方案1】:

如何在 iOS 版 Chrome 上拦截 AJAX 请求

这是适用于大多数浏览器的 XMLHttpRequest 拦截代码:

(function(open) {
  XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
    // Intercept the open request here
    alert("Intercepted: " + url);
    open.apply(this, arguments);
  };
})(XMLHttpRequest.prototype.open);

xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET","http://google.com",true);
xmlhttp.send();

iOS 版 Chrome 存在问题。它已在下面提出和调查。我将解释“重复的open() 调用”错误、演示和解决方法。

从最后的参考:

在页面加载时,Chrome 会向以下服务发出两个异步请求 它可能在本地运行。通过 URL 的声音 请求,这些服务用于确保页面的安全 您正在访问。

这是 Chrome 尝试访问的一个此类本地 URL 的屏幕截图 (Demo):

Chrome 会定期自行调用XMLHttpRequest.open()。这些对拦截代码的重复调用不是由拦截代码本身引起的;它们是由来自 Chrome 浏览器的不相关和重复调用引起的。我已经确定了两个这样的 URL。可能还有其他人。

根据我的研究,这种解决方法使 XMLHttpRequest 代码拦截工作在 Chrome for iOS 上。请参阅此JSBin 测试演示。它也将演示如何这些重复调用。本质上,拦截代码应该忽略 Chrome 使用的 URL。

(function(open) {
  XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
    var d1 = document.getElementById('urls');

    // Avoid intercepting Chrome on iOS local security check urls
    if(url.indexOf("/chromecheckurl") < 0 && url.indexOf("/chrome") !== 0) {
        // These are what we want to intercept
        d1.insertAdjacentHTML('beforeend', '<b>'+url+'</b><br/>');
    } else {
        // These are the internal Chrome requests - we can ignore them
        d1.insertAdjacentHTML('beforeend', '<i>'+url+'</i><br/>');
    }

    open.apply(this, arguments);
  };
})(XMLHttpRequest.prototype.open);


xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET","http://google.com",true);
xmlhttp.send();

这是我对 iOS 版 Chrome 上这个“重复的open() 调用”错误的最佳尝试以及解决方法。

【讨论】:

  • @NinGenShinRa 请确认此演示适用于 iOS 版 Chrome
  • 感谢您的回答,但这不是问题所在:jsfiddle 可能会避免无限警报循环,但是 same code on jsbin 显示了上述问题。我很好奇,为什么你认为这会解决问题呢?当然,范围界定很棒(这就是我在原始代码中所做的),但是这种帮助背后的基本原理是什么? (问一下,也许我以后可以避免类似的陷阱)
  • 哦,有趣!让我调查一下。在我详细解释我怀疑是什么问题之前,我希望你确认它是否有效。也许我可以拿回那票;)
  • 这确实是正确答案。您链接的Chrome issue 确实是在此问题之后提交的,并使用我的 JSBin 作为最小示例案例。感谢您的研究!
猜你喜欢
  • 2013-05-24
  • 2011-12-26
  • 1970-01-01
  • 1970-01-01
  • 2013-02-02
  • 2016-06-18
  • 1970-01-01
  • 2010-11-21
  • 1970-01-01
相关资源
最近更新 更多