web-dev-qa-db-ja.com

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

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

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);
101
mettjus

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

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


IEでは、Ajaxを実行するActiveXObject制御メソッドを使用しようとするコードをキャッチしません。よく書かれたコードは、最初にXMLHttpRequestオブジェクトを探し、それが使用可能な場合はそれを使用し、IE 7.以降使用可能です。しかし、使用可能な場合はActiveXObjectメソッドを使用するコードがあります。 IEの以降のバージョン。


最新のブラウザには、 fetch() interface などのAjax呼び出しを発行する他の方法があります。そのため、すべてのAjax呼び出しをフックしようとする場合は、XMLHttpRequest以外にもフックする必要があります。

32
jfriend00

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

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

参照: CanIuse

3

Ajax-hook は、グローバルXMLHttpRequestオブジェクトをフックし、デフォルトのAjax要求と応答を変更するためのオープンソースライブラリです。 github: https://github.com/wendux/Ajax-hook 、例:

hookAjax({

  //hook callbacks
  onreadystatechange:function(xhr){
   console.log("onreadystatechange called: %O",xhr)
  },

  onload:function(xhr){
   console.log("onload called: %O",xhr)
  },

  //hook function
  open:function(arg,xhr){
   console.log("open called: method:%s,url:%s,async:%s",arg[0],arg[1],arg[2])
  }

})
3
wendu

Firefox AMO Editor Rob Wが親切に指摘したように、

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

...

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

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

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

2
Walty Yeung