Патч обезьяны XMLHTTPRequest.внутренний

как бы пойти о обезьяне латать XMLHTTPRequest ' s

3 ответов


В манки-патч XMLHttpRequests, вам нужно знать, как обычно строится запрос 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 обработчик. Для простоты, я не включил код другие события, такие как onload. Кроме того, я не учитывал события, добавленные с помощью addEventListener.

предыдущий патч выполняется для всех запросов. Но что, если вы хотите ограничить патч только определенным запросом? Запрос с определенным 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);
};

мои примеры очень простые, и могут быть расширены, чтобы удовлетворить ваши точные пожелания. Однако это зависит от вас.


вы можете узнать Ajax-hook написано по-китайски!

это расширенный js, чтобы включить патч обезьяны XMLHTTPRequest


предполагая, что вы можете игнорировать 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;
}