1. ホーム
  2. javascript

[解決済み] 異なるJSライブラリによるすべてのAJAXリクエストをインターセプトする方法

2022-09-03 07:15:25

質問

私はさまざまな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);

どのように解決するのですか?

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

そして、唯一のパフォーマンスへの影響は、各メソッドに対して1つの余分な関数呼び出しだけです。 .open() に加えて、ネットワーク呼び出しが関与しているときにはおそらく重要ではない、あなた自身が実行するどんなコードであってもです。


IE では、これは ActiveXObject コントロールメソッドを使って Ajax を実行しようとするコードは捕まりません。 よくできたコードでは、まず XMLHttpRequest オブジェクトを探し、利用可能であればそれを使用します(IE 7 から利用可能)。 しかし、いくつかのコードでは ActiveXObject メソッドを使用するコードがあるかもしれません。


最近のブラウザでは、Ajax 呼び出しを発行する他の方法があります。 fetch() インターフェース ですから、もしすべての Ajax 呼び出しをフックしたいのであれば、単に XMLHttpRequest .