Abfangen aller AJAX-Anforderungen, die von verschiedenen JS-Bibliotheken gestellt wurden


110

Ich erstelle eine Web-App mit verschiedenen JS-Bibliotheken (AngularJS, OpenLayers, ...) und benötige eine Möglichkeit, alle AJAX-Antworten abzufangen 401 Unauthorized, um ihn umleiten zu können, falls die protokollierte Benutzersitzung abgelaufen ist (Antwort erhält den Status zurück) zur Anmeldeseite.

Ich weiß, dass AngularJS interceptorssolche Szenarien anbietet , konnte jedoch keinen Weg finden, um eine solche Injektion in OpenLayers-Anforderungen zu erreichen. Also habe ich mich für einen Vanille-JS-Ansatz entschieden.

Hier habe ich diesen Code gefunden ...

(function(open) {

    XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {

        this.addEventListener("readystatechange", function() {
            console.log(this.readyState); // this one I changed
        }, false);

        open.call(this, method, url, async, user, pass);
    };

})(XMLHttpRequest.prototype.open);

... was ich angepasst habe und so aussieht, als ob es sich wie erwartet verhält (nur auf dem letzten Google Chrome getestet).

Da es den Prototyp von XMLHTTPRequest modifiziert, frage ich mich, wie gefährlich dies sein könnte oder ob es ernsthafte Leistungsprobleme verursachen könnte. Und gibt es übrigens eine gültige Alternative?

Update: So fangen Sie Anforderungen ab, bevor sie gesendet werden

Der vorherige Trick funktioniert in Ordnung. Aber was ist, wenn Sie in derselben Umgebung einige Header einfügen möchten, bevor die Anfrage gesendet wird? Mach Folgendes:

(function(send) {

    XMLHttpRequest.prototype.send = function(data) {

        // in this case I'm injecting an access token (eg. accessToken) in the request headers before it gets sent
        if(accessToken) this.setRequestHeader('x-access-token', accessToken);

        send.call(this, data);
    };

})(XMLHttpRequest.prototype.send);

4
Scheint mir vollkommen sicher zu sein.
Barmar

Die einzige Auswirkung auf die Leistung besteht darin, dass bei jeder AJAX-Antwort eine zusätzliche Funktion ausgeführt wird, aber genau das möchten Sie tun.
Barmar

Ich habe nach so etwas gesucht. Vielen Dank
Silver Moon

Antworten:


36

Diese Art des Funktionshakens ist absolut sicher und wird aus anderen Gründen regelmäßig mit anderen Methoden durchgeführt.

Die einzige Auswirkung auf die Leistung ist nur ein zusätzlicher Funktionsaufruf für jeden .open()Code sowie den Code, den Sie selbst ausführen. Dies ist wahrscheinlich unerheblich, wenn es sich um einen Netzwerkaufruf handelt.


Im IE wird dadurch kein Code abgefangen, der versucht, die ActiveXObjectSteuerungsmethode von Ajax zu verwenden. Gut geschriebener Code sucht zuerst nach dem XMLHttpRequestObjekt und verwendet diesen, falls verfügbar und seit IE 7 verfügbar. Es kann jedoch auch Code geben, der die ActiveXObjectMethode verwendet, wenn er verfügbar ist, was in viel späteren Versionen des IE der Fall wäre.


In modernen Browsern gibt es andere Möglichkeiten, Ajax-Aufrufe auszugeben, z. B. die fetch()Benutzeroberfläche. Wenn Sie also alle Ajax-Aufrufe verknüpfen möchten, müssen Sie mehr als nur eine Verbindung herstellen XMLHttpRequest.


1
Hi @ jfriend00 - wie würden Sie alle Abruf-API-Anfragen verknüpfen - stackoverflow.com/questions/44728723/… ?
Colemerrick

1
@bagofcole - Vermutlich könnten Sie die fetch()Funktion mit einem Affen-Patch versehen , um alle Aufrufe abzufangen - obwohl ich das selbst noch nie versucht habe. Es sieht so aus, als ob dieses Modul das tut.
jfriend00

Bricht YouTube ab, wenn versucht wird, comment_service_ajaxAnfragen zu verknüpfen.
Leeroy

3

Dies fängt XMLHttpRequests für einige Versionen von IE (9 und niedriger) nicht ab . Abhängig von der Bibliothek suchen sie möglicherweise zuerst nach dem proprietären ActiveX-Steuerelement des IE.

Und natürlich sind alle Wetten ungültig, wenn Sie einen nicht strengen DOCTYPE unter IE verwenden, aber ich bin sicher, dass Sie das gewusst haben.

Referenz: CanIuse


2

Wie von Firefox AMO Editor freundlicherweise hervorgehoben Rob W,

Der folgende Code ändert das Verhalten von XMLHttpRequest. Wenn der dritte Parameter ("async") nicht angegeben ist, wird standardmäßig true verwendet. Wenn es angegeben und undefiniert ist, entspricht es "false", wodurch eine Anforderung in eine synchrone HTTP-Anforderung umgewandelt wird. Dadurch wird die Benutzeroberfläche blockiert, während die Anforderung verarbeitet wird, und einige Funktionen der XMLHttpRequest-API sind ebenfalls deaktiviert.

...

Um dies zu beheben, ersetzen Sie open.call (....) durch open.apply (dies, Argumente);

Und hier ist ein Referenzlink:

https://xhr.spec.whatwg.org/#the-open()-method


(wobei "Der folgende Code" sich auf den Ausschnitt aus der Frage bezieht)
Rob W
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.