Может ли JQuery прослушивать вызовы AJAX из другого javascript?

Мне нужно встроить функцию в корзину покупок, которая использует AJAX для получения обновленной копии шаблона с сервера, когда что-то меняется (например, удаляется продукт). Я не могу изменить код на стороне сервера или JavaScript, который заставляет корзину работать в первую очередь. (Не идеал я знаю, но так оно и есть)

Я хочу запускать свой собственный JavaScript каждый раз, когда корзина обновляется. Я хочу знать, возможно ли прослушивать AJAX-вызовы и запускать мой код каждый раз, когда он создается.

5 ответов

Решение

Чтобы выполнить все вызовы AJAX в документе HTML, вы можете перезаписать XMLHttpRequest прототип. Таким образом, вы можете следить за действиями по методам XMLHttpRequest объекты.

Вот небольшой пример кода:

var open = window.XMLHttpRequest.prototype.open,
    send = window.XMLHttpRequest.prototype.send,
    onReadyStateChange;

function openReplacement(method, url, async, user, password) {
    var syncMode = async !== false ? 'async' : 'sync';
    console.warn(
        'Preparing ' +
        syncMode +
        ' HTTP request : ' +
        method +
        ' ' +
        url
    );
    return open.apply(this, arguments);
}

function sendReplacement(data) {
    console.warn('Sending HTTP request data : ', data);

    if(this.onreadystatechange) {
        this._onreadystatechange = this.onreadystatechange;
    }
    this.onreadystatechange = onReadyStateChangeReplacement;

    return send.apply(this, arguments);
}

function onReadyStateChangeReplacement() {
    console.warn('HTTP request ready state changed : ' + this.readyState);
    if(this._onreadystatechange) {
        return this._onreadystatechange.apply(this, arguments);
    }
}

window.XMLHttpRequest.prototype.open = openReplacement;
window.XMLHttpRequest.prototype.send = sendReplacement;

В этом примере для каждого вызова AJAX вы увидите предупреждение в консоли JavaScript.

Это не скрипт JQuery, но вы можете использовать JQuery внутри, как вы хотите.

Это решение, вероятно, не будет работать на IE 6 или старше, но оно работает в FF, IE7+, Chrome, Opera, Safari...

Я бы предпочел это решение.

$(document).ajaxComplete(function(event,request, settings){
    // Your code here
});

Мой друг, вы можете сделать это очень легко с помощью Jquery (как вы уже сказали, что используете Jquery)

(Для тех, кто не использует, они могут ввести код библиотеки Jquery в функции ajax для просмотра собственного кода:'))

$(document).bind("ajaxSend", function(){
   $("#loading").show();
 }).bind("ajaxComplete", function(){
   $("#loading").hide();
 });

Это фрагмент кода, взятый из официальных документов API jquery (см. Раздел "Глобальные события").

https://api.jquery.com/Ajax_Events/

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

http://plugins.jquery.com/plugin-tags/periodic-updater

При этом используется тот же подход - добавление обратного вызова в прототипе XHR, но без установки каких-либо новых свойств в прототипе или написания нашего собственного механизма цепочки событий. Я думаю, что это менее вероятно, чтобы вызвать конфликты.

(function() {
  // Reference to the original prototype method we're overriding
  var originalOpen = XMLHttpRequest.prototype.open;

  // Override prototype.open to add a custom callback whenever a request is opened
  XMLHttpRequest.prototype.open = function() {
    this.addEventListener('loadend', customCallback);

    // Execute the original prototype.open without affecting its execution context
    originalOpen.apply(this, arguments);
  };

  // All instances of XMLHttpRequest will execute this callback once on readyState 4
  var customCallback = function () {
    // In this context, `this` refers to the XHR instance that just completed
    console.log(this);

    // Remove the invoking listener to prevent duping on multiple calls to .open
    this.removeEventListener('loadend', customCallback);
  }
}());

Это не будет работать в IE <= 8 (нет поддержки .addEventListener())

Другие вопросы по тегам