Intercepting AJAX requests on Chrome for iOS?

喜夏-厌秋 提交于 2020-01-02 07:30:22

问题


I intercept AJAX requests in my site by altering the XMLHttpRequest.prototype open and send methods. This method worked without any troubles in all the browsers I tested. However, when it comes to Chrome for iOS (iPhone) the code has the weirdest bug: it's like it continuously fire the code I changed in the prototype (ending up crashing, obviously).

Here's a super-minimal example of what I am doing:

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
 };

I've assembled a little JSBin doing just that you can visit with your Chrome on iOS: Demo

According to this answer, the code I'm using (essentially the same as the one OP in that answer is going to use) is safe and there should be no reason to worry. And, as a matter of fact, Chrome for iOS is the only browser which behaves weirdly.

This has been driving me nuts for two days, any suggestion or workaround appreciated.


回答1:


How to Intercept AJAX requests on Chrome for iOS

This is XMLHttpRequest interception code that works on most browsers:

(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();

There is a problem in Chrome for iOS. It has been raised and investigated below. I will provide an explanation for the "repeated open() calls" bug, a demonstration, and a workaround.

  • Modifying the prototype for XMLHttpRequest makes it fire continuously in Chrome for iOS

  • Crazy Things We Found Developing New Relic Browser

  • Chrome on iOS might eat your global variable!

From the last reference:

On page load, Chrome makes two asynchronous requests to services that it is presumably running locally. By the sound of the URLs it’s requesting, these services are used to ensure the safety of the page you are accessing.

And here is a screenshot of one such local URL Chrome is trying to access (Demo):

Chrome calls XMLHttpRequest.open() periodically on it's own. These repeated calls to the interception code are not caused by the interception code itself; they are caused by unrelated and repeated calls from the Chrome browser. I've identified two such URLs. There may be others.

  • /chromeforiossecurity/b86 ... 98d/
  • https://localhost:0/chromecheckurl

From my research, this workaround makes the XMLHttpRequest code interception work on Chrome for iOS. See this JSBin testing demo. It will demonstrate just how these repeated calls come about too. Essentially, the interception code should ignore URLs used by Chrome.

(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();

This is my best attempt at an explanation about this "repeated open() calls" bug on Chrome for iOS, and a workaround.



来源:https://stackoverflow.com/questions/29310298/intercepting-ajax-requests-on-chrome-for-ios

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!