2009-03-10 13 views

Antwort

0

Nicht sicher, ob Sie es mit dem Greymonkey ausführen können, aber wenn Sie eine Erweiterung erstellen, können Sie den Observator-Dienst und den HTTP-Beobachter verwenden.

3

Wie ändern Sie die XMLHttpRequest.prototype.open oder senden Methoden mit Ersetzungen, die eigene Callbacks einrichten und die ursprünglichen Methoden aufrufen? Der Callback kann sein Ding tun und dann den Callback den angegebenen Originalcode aufrufen.

Mit anderen Worten:

XMLHttpRequest.prototype.realOpen = XMLHttpRequest.prototype.open; 

var myOpen = function(method, url, async, user, password) { 
    //do whatever mucking around you want here, e.g. 
    //changing the onload callback to your own version 


    //call original 
    this.realOpen (method, url, async, user, password); 
} 


//ensure all XMLHttpRequests use our custom open method 
XMLHttpRequest.prototype.open = myOpen ; 
1

Sie können das unsafeWindow.XMLHttpRequest Objekt in dem Dokument mit einem Wrapper ersetzen. Ein wenig Code (nicht getestet):

var oldFunction = unsafeWindow.XMLHttpRequest; 
unsafeWindow.XMLHttpRequest = function() { 
    alert("Hijacked! XHR was constructed."); 
    var xhr = oldFunction(); 
    return { 
    open: function(method, url, async, user, password) { 
     alert("Hijacked! xhr.open()."); 
     return xhr.open(method, url, async, user, password); 
    } 
    // TODO: include other xhr methods and properties 
    }; 
}; 

Das hat aber ein kleines Problem: Greasemonkey-Skripte ausführen nach eine Seite geladen wird, so kann die Seite der ursprünglichen XMLHttpRequest-Objekt verwenden oder lagern während es Ladesequenz ist, so Anfragen Vor der Ausführung Ihres Skripts oder mit dem echten XMLHttpRequest-Objekt wurde Ihr Skript nicht verfolgt. Keine Möglichkeit, dass ich diese Einschränkung umgehen kann.

34

Die akzeptierte Antwort ist fast richtig, aber es könnte eine leichte Verbesserung verwenden:

(function(open) { 
    XMLHttpRequest.prototype.open = function() { 
     this.addEventListener("readystatechange", function() { 
      console.log(this.readyState); 
     }, false); 
     open.apply(this, arguments); 
    }; 
})(XMLHttpRequest.prototype.open); 

Bevorzugen + Argumente über Anruf mit anwenden, weil dann nicht Sie haben explizit alle offenen Argumente zu kennen, die sich ändern können!

0

in Chrome Getestet 55 und Firefox 50.1.0

In meinem Fall habe ich die response, die in Firefox war eine schreibgeschützte Eigenschaft ändern wollte, so hatte ich das ganze XMLHttpRequest-Objekt zu wickeln. Ich habe nicht die gesamte API (insbesondere den responseType) implementiert, aber es war gut genug für alle Bibliotheken, die ich habe.

Verbrauch:

XHRProxy.addInterceptor(function(method, url, responseText, status) { 
     if (url.endsWith('.html') || url.endsWith('.htm')) { 
      return "<!-- HTML! -->" + responseText; 
     } 
    }); 

Code:

(function(window) { 

    var OriginalXHR = XMLHttpRequest; 

    var XHRProxy = function() { 
     this.xhr = new OriginalXHR(); 

     function delegate(prop) { 
      Object.defineProperty(this, prop, { 
       get: function() { 
        return this.xhr[prop]; 
       }, 
       set: function(value) { 
        this.xhr.timeout = value; 
       } 
      }); 
     } 
     delegate.call(this, 'timeout'); 
     delegate.call(this, 'responseType'); 
     delegate.call(this, 'withCredentials'); 
     delegate.call(this, 'onerror'); 
     delegate.call(this, 'onabort'); 
     delegate.call(this, 'onloadstart'); 
     delegate.call(this, 'onloadend'); 
     delegate.call(this, 'onprogress'); 
    }; 
    XHRProxy.prototype.open = function(method, url, async, username, password) { 
     var ctx = this; 

     function applyInterceptors(src) { 
      ctx.responseText = ctx.xhr.responseText; 
      for (var i=0; i < XHRProxy.interceptors.length; i++) { 
       var applied = XHRProxy.interceptors[i](method, url, ctx.responseText, ctx.xhr.status); 
       if (applied !== undefined) { 
        ctx.responseText = applied; 
       } 
      } 
     } 
     function setProps() { 
      ctx.readyState = ctx.xhr.readyState; 
      ctx.responseText = ctx.xhr.responseText; 
      ctx.responseURL = ctx.xhr.responseURL; 
      ctx.responseXML = ctx.xhr.responseXML; 
      ctx.status = ctx.xhr.status; 
      ctx.statusText = ctx.xhr.statusText; 
     } 

     this.xhr.open(method, url, async, username, password); 

     this.xhr.onload = function(evt) { 
      if (ctx.onload) { 
       setProps(); 

       if (ctx.xhr.readyState === 4) { 
        applyInterceptors(); 
       } 
       return ctx.onload(evt); 
      } 
     }; 
     this.xhr.onreadystatechange = function (evt) { 
      if (ctx.onreadystatechange) { 
       setProps(); 

       if (ctx.xhr.readyState === 4) { 
        applyInterceptors(); 
       } 
       return ctx.onreadystatechange(evt); 
      } 
     }; 
    }; 
    XHRProxy.prototype.addEventListener = function(event, fn) { 
     return this.xhr.addEventListener(event, fn); 
    }; 
    XHRProxy.prototype.send = function(data) { 
     return this.xhr.send(data); 
    }; 
    XHRProxy.prototype.abort = function() { 
     return this.xhr.abort(); 
    }; 
    XHRProxy.prototype.getAllResponseHeaders = function() { 
     return this.xhr.getAllResponseHeaders(); 
    }; 
    XHRProxy.prototype.getResponseHeader = function(header) { 
     return this.xhr.getResponseHeader(header); 
    }; 
    XHRProxy.prototype.setRequestHeader = function(header, value) { 
     return this.xhr.setRequestHeader(header, value); 
    }; 
    XHRProxy.prototype.overrideMimeType = function(mimetype) { 
     return this.xhr.overrideMimeType(mimetype); 
    }; 

    XHRProxy.interceptors = []; 
    XHRProxy.addInterceptor = function(fn) { 
     this.interceptors.push(fn); 
    }; 

    window.XMLHttpRequest = XHRProxy; 

})(window); 
Verwandte Themen