7

XMLHTTPRequestモンキーパッチを'のonreadystatechange関数に適用するにはどうすればよいでしょうか。ページから行われたすべてのajaxリクエストが戻ってきたときに呼び出される関数を追加しようとしています。

これはひどい考えのように聞こえますが、ユースケースは非常に独特です。コンソール(jqconsole)で特定のSDKを使用したいのですが、外部SDKを変更せずに、コンソール内でajax呼び出しのステータスと結果を表示します。

私は素晴らしい情報を持っているこの投稿を見ましたが、私のJavaScriptスキルを超えているように見えるコールバックにパッチを当てるモンキーパッチについては何もありません。

XMLHTTPRequestsPS jQueryは、直接からではなくjQueryから行われたajax呼び出しのみをサポートしているため、使用できません。これは、ここでのケースです。

4

3 に答える 3

12

モンキーパッチXMLHttpRequestを適用するには、AJAXリクエストが一般的にどのように構築されるかを知る必要があります。

  1. コンストラクターの呼び出し
  2. リクエストの準備(setRequestHeader()open()
  3. リクエストの送信(.send)。

汎用パッチ

(function(xhr) {
    function banana(xhrInstance) { // Example
        console.log('Monkey RS: ' + xhrInstance.readyState);
    }
    // Capture request before any network activity occurs:
    var send = xhr.send;
    xhr.send = function(data) {
        var rsc = this.onreadystatechange;
        if (rsc) {
            // "onreadystatechange" exists. Monkey-patch it
            this.onreadystatechange = function() {
                banana(this);
                return rsc.apply(this, arguments);
            };
        }
        return send.apply(this, arguments);
    };
})(XMLHttpRequest.prototype);

以前は、ハンドラーonreadystatechangeに割り当てられていると想定していました。簡単にするために、などの他のイベントonreadystatechangeのコードは含めませんでした。また、を使用して追加されたイベントは考慮していません。onloadaddEventListener

以前のパッチはすべてのリクエストに対して実行されます。しかし、パッチを特定のリクエストのみに制限したい場合はどうでしょうか。特定のURLまたは非同期フラグと特定のリクエスト本文を持つリクエスト?

条件付きモンキーパッチ

POST例:リクエスト本文に「TEST」が含まれているすべてのリクエストをインターセプトする

(function(xhr) {
    function banana(xhrInstance) { // Example
        console.log('Monkey RS: ' + xhrInstance.readyState);
    }
    // 
    var open = xhr.open;
    xhr.open = function(method, url, async) {
        // Test if method is POST
        if (/^POST$/i.test(method)) {
            var send = this.send;
            this.send = function(data) {
                // Test if request body contains "TEST"
                if (typeof data === 'string' && data.indexOf('TEST') >= 0) {
                    var rsc = this.onreadystatechange;
                    if (rsc) {
                        // Apply monkey-patch
                        this.onreadystatechange = function() {
                            banana(this);
                            return rsc.apply(this, arguments);
                        };
                    }
                }
                return send.apply(this, arguments);
            };
        }
        return open.apply(this, arguments);
    };
})(XMLHttpRequest.prototype);

使用される主な手法は、...を使用した透過的な書き換えです。

var original = xhr.method; 
xhr.method = function(){
    /*...*/;
    return original.apply(this, arguments);
};

私の例は非常に基本的なものであり、あなたの正確な希望に合わせて拡張することができます。ただし、それはあなた次第です。

于 2012-09-25T08:31:44.400 に答える
0

IEを無視できると仮定して...

//Totally untested code, typed at the SO <textarea>... but the concept *should* work, let me know if it doesn't.
var OldXMLRequest = XMLHttpRequest;

// Create a new instance
function XMLHttpRequest() {
  var ajax = new OldXMLRequest();

  // save old function
  var f = ajax.onreadystatechange;
  ajax.onreadystatechange = function() {
    console.log("Whatever!");
    f(); // Call the old function
  }
  return ajax;
}
于 2012-09-25T04:39:42.233 に答える
0

中国語で書かれたAjax-hookから学ぶことができます!

モンキーパッチXMLHTTPRequestを有効にする高度なjsです

于 2017-06-03T14:39:06.493 に答える