【问题标题】:Intercept all ajax calls?拦截所有ajax调用?
【发布时间】:2011-10-16 14:39:09
【问题描述】:

我正在尝试拦截所有 AJAX 调用,以检查该 AJAX 响应是否包含我从我的 PHP 脚本作为 JSON 发送的特定错误代码(代码:ACCESS_DENIED、SYSTEM_ERROR、NOT_FOUND)。

我知道有人可以这样做:

$('.log').ajaxSuccess(function(e, xhr, settings) {
});

但是 - 仅当“ajaxSuccess”事件冒泡到 .log div 时才有效?我对么?我可以通过将“ajaxSuccess”事件绑定到文档来实现我想要的吗?

$(document).ajaxSuccess(function(e, xhr, settings) {
});

我可以在 jQuery 或原始 JavaScript 中做到这一点。

【问题讨论】:

标签: javascript jquery ajax dom-events


【解决方案1】:

如果您使用 jQuery,$.ajaxSuccess 是一个不错的选择,但这里有一个更通用的选项,它将拦截来自所有框架的 XHR 调用(我已经使用 ExtJS 和 jQuery 对其进行了测试 - 即使多个框架同时加载)。它已经过测试,可与 IE8、Chrome 和 Firefox 一起使用。

(function(XHR) {
    "use strict";

    var open = XHR.prototype.open;
    var send = XHR.prototype.send;

    XHR.prototype.open = function(method, url, async, user, pass) {
        this._url = url;
        open.call(this, method, url, async, user, pass);
    };

    XHR.prototype.send = function(data) {
        var self = this;
        var oldOnReadyStateChange;
        var url = this._url;

        function onReadyStateChange() {
            if(self.readyState == 4 /* complete */) {
                /* This is where you can put code that you want to execute post-complete*/
                /* URL is kept in this._url */
            }

            if(oldOnReadyStateChange) {
                oldOnReadyStateChange();
            }
        }

        /* Set xhr.noIntercept to true to disable the interceptor for a particular call */
        if(!this.noIntercept) {            
            if(this.addEventListener) {
                this.addEventListener("readystatechange", onReadyStateChange, false);
            } else {
                oldOnReadyStateChange = this.onreadystatechange; 
                this.onreadystatechange = onReadyStateChange;
            }
        }

        send.call(this, data);
    }
})(XMLHttpRequest);

我已经发布了一个more specific example on github,它会拦截 AJAX 调用并将 AJAX 调用持续时间发送回服务器进行统计分析。

【讨论】:

  • 根据您的实现,我在 NPM 上发布了一些适用于请求和响应的内容! github.com/slorber/ajax-interceptor
  • 太棒了。最近比这个答案,我一直在使用这种技术将 CSRF 标头添加到我们的一些 AJAX 请求中。将来我会考虑使用你的库。
  • 仅适用于使用此方法并希望访问 ajax 调用的响应数据的任何人。您可以通过self.response 获得onReadyStateChange() 方法中的响应。
  • 如何阻止脚本拦截 jquery.ajax 调用?我必须在哪里插入 noIntercept 值?
【解决方案2】:

用于拦截 ajax 调用的原始 javacript 代码:

(function(send) {
    XMLHttpRequest.prototype.send = function(body) {
        var info="send data\r\n"+body;
        alert(info);
        send.call(this, body);
    };
})(XMLHttpRequest.prototype.send);

拦截ajax的jQuery代码:

$.ajaxSetup({
    beforeSend: function (xhr,settings) {
        alert(settings.data);
        alert(settings.url);
    }
});

参考:http://myprogrammingnotes.com/intercept-ajax-calls-jquery.html

【讨论】:

    【解决方案3】:

    来自http://api.jquery.com/ajaxSuccess/

    只要一个 Ajax 请求成功完成,jQuery 就会触发 ajaxSuccess 事件。此时会执行所有已使用 .ajaxSuccess() 方法注册的处理程序。

    所以选择器并没有定义你“捕捉”事件的位置(因为,老实说,ajax 事件本质上不是从 DOM 元素开始的),而是定义了处理的范围被默认(即this 将指向那个/那些元素)。

    总之——它应该正是你想要的

    【讨论】:

      【解决方案4】:

      最好的方法,我发现https://lowrey.me/intercept-2/

      const intercept = (urlmatch, callback) => {
        let send = XMLHttpRequest.prototype.send;
        XMLHttpRequest.prototype.send = function() {
          this.addEventListener('readystatechange', function() {
            if (this.responseURL.includes(urlmatch) && this.readyState === 4) {
              callback(this);
            }
          }, false);
          send.apply(this, arguments);
        };
      };
      

      【讨论】:

        【解决方案5】:

        尝试使用 Mockjax.js http://code.appendto.com/plugins/jquery-mockjax

        它允许您劫持对服务器的 AJAX 调用并模拟该位置。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-10-05
          • 1970-01-01
          • 2017-04-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-11-21
          • 1970-01-01
          相关资源
          最近更新 更多