異なるJSライブラリによって作成されたすべてのAJAXリクエストをインターセプトする方法


110

私はさまざまなJSライブラリ(AngularJS、OpenLayersなど)を使用してWebアプリを構築しており、ログに記録されたユーザーセッションが期限切れになった場合(応答が401 Unauthorizedステータスで戻る)にリダイレクトできるように、すべてのAJAX応答をインターセプトする方法が必要ですログインページへ。

AngularJSがinterceptorsそのようなシナリオを管理するために提供していることを知っていますが、OpenLayersリクエストへのそのような注入を実現する方法を見つけることができませんでした。だから私はバニラJSアプローチを選びました。

ここで私はこのコードを見つけました...

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

...私はそれを適応させ、期待どおりに動作するように見えます(最後のGoogle Chromeでのみテストしました)。

XMLHTTPRequestのプロトタイプを変更するときに、これがどれほど危険であるか、または深刻なパフォーマンスの問題を引き起こす可能性があるのか​​と思います。そしてところで、有効な代替案はありますか?

更新:リクエストが送信される前にインターセプトする方法

前のトリックは大丈夫です。しかし、同じシナリオで、リクエストが送信される前にヘッダーを挿入したい場合はどうでしょうか?以下をせよ:

(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
私には完全に安全なようです。
Barmar 14

唯一のパフォーマンスへの影響は、すべてのAJAX応答中に追加の関数を実行することですが、それはあなたがしたいことです。
Barmar 14

私はこのようなものを探していました。どうもありがとう
シルバームーン

回答:


36

このタイプの関数フックは完全に安全であり、他の理由で他のメソッドで定期的に行われます。

また、パフォーマンスへの唯一の影響は、実際には、各関数に対して1つの追加の関数呼び出しと.open()、ネットワーク呼び出しが含まれる場合には重要ではない、自分で実行したコードです。


IEでは、これはActiveXObjectAjaxを実行する制御メソッドを使用しようとするコードをキャッチしません。適切に記述されたコードは、最初にXMLHttpRequestオブジェクトを探し、使用可能な場合はそれを使用します。それは、IE 7以降で使用可能です。ただし、使用ActiveXObject可能な場合、メソッドを使用するコードが存在する可能性があります。


最近のブラウザーでは、fetch()インターフェースなどのAjax呼び出しを発行する方法が他にもあるため、すべてのAjax呼び出しをフックする場合は、だけではなくフックする必要がありXMLHttpRequestます。


1
こんにちは@ jfriend00 - -あなたはどのようにすべてのAPIリクエストをフェッチフックうstackoverflow.com/questions/44728723/...を
colemerrick 2017年

1
@bagofcole- fetch()関数へのすべての呼び出しをインターセプトするために、おそらく関数をモンキーパッチすることができます-私は自分で試したことはありません。このモジュールはそうしているようです。
jfriend00 2017年

comment_service_ajaxリクエストをフックしようとするとYouTubeが機能しなくなります。
Leeroy

3

これは、IEの一部のバージョン(9以下)の XMLHttpRequestsをキャッチしません。ライブラリによっては、最初にIE独自のActiveXコントロールを探す場合があります。

そしてもちろん、IEで非厳密なDOCTYPEを使用している場合、すべての賭けは無効になりますが、私はあなたがそれを知っていると確信しています。

リファレンス:CanIuse


2

Firefox AMO Editorによって親切に指摘されたようにRob W

次のコードは、XMLHttpRequestの動作を変更します。デフォルトでは、3番目の(「async」)パラメーターが指定されていない場合、デフォルトでtrueになります。これが指定されていて未定義の場合は、同期HTTPリクエストでリクエストを変換する「false」と同等です。これにより、リクエストの処理中にUIがブロックされ、XMLHttpRequest APIの一部の機能も無効になります。

...

これを修正するには、open.call(....)をopen.apply(this、arguments)に置き換えます。

そしてここに参照リンクがあります:

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


(「次のコード」は質問のスニペットを指します)
Rob W
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.