Search code examples
javascriptjqueryxmlhttprequestgreasemonkeyuserscripts

Detect XHR request


I'd like to fire a function when the site does a XHR request. I have tried many suggestions posted on stackoverflow, but it doesn't seem to work for my userscript. So I decided to ask it myself. Hopefully you can help.

The function I want to call uses GM_setValue and GM_getValue, so that makes it also more difficult. I also tried the function below and similar functions, but it only works when using it in the JavaScript console. When I use it with a userscript it doesn't work anymore... I've also tried waitForKeyElements, but that doesn't seem to work for me. And setTimeout and setInterval is not really an option. Please help. Thanks in advance!

var oldXHR = window.XMLHttpRequest;
function newXHR() {
    var realXHR = new oldXHR();
    realXHR.addEventListener("readystatechange", function() {
        if(realXHR.readyState==4 && realXHR.status==200){
            afterAjaxComplete() //run your code here
        }
    }, false);
    return realXHR;
}
window.XMLHttpRequest = newXHR;

Solution

  • Override the default XMLHttpRequest methods with custom ones, and catch the needed events:

    var open = window.XMLHttpRequest.prototype.open,
      send = window.XMLHttpRequest.prototype.send;
    
    function openReplacement(method, url, async, user, password) {
      this._url = url;
      return open.apply(this, arguments);
    }
    
    function sendReplacement(data) {
      if(this.onreadystatechange) {
        this._onreadystatechange = this.onreadystatechange;
      }
      this.onreadystatechange = onReadyStateChangeReplacement;
      return send.apply(this, arguments);
    }
    
    function onReadyStateChangeReplacement() {
    
      //YOUR CODE FOR READYSTATECHANGE
    
      if(this._onreadystatechange) {
        return this._onreadystatechange.apply(this, arguments);
      }
    }
    
    window.XMLHttpRequest.prototype.open = openReplacement;
    window.XMLHttpRequest.prototype.send = sendReplacement;
    

    Update: read this post for more info on the approach and examples.