首页 > 语言 > JavaScript > 正文

分享JavaScript监听全部Ajax请求事件的方法

2024-05-06 14:52:23
字体:
来源:转载
供稿:网友

若Ajax请求是由jQuery的$.ajax发起的,默认情况下可以使用 jQuery的Global Ajax Event Handlers监听到Ajax事件,然而我遇到的却是用原生JavaScript发起的Ajax请求,所以这种方法行不通。

然后呢,还有其他方法,比如说 Pub/Sub,但是这个发起请求的 js 代码我是无法改动的,也就不存在向代码里添加 publish 的问题。同理,jQuery 的 .bind.trigger 也无法使用。

最后,决定使用直接 override XMLHttpRequest,同时配合使用自定义事件。 

在 StackOverflow 上搜索,发现有个歪果仁给出了一个不靠谱的解决方法,嗯,贴出来给大家看看:

;(function () { var open = window.XMLHttpRequest.prototype.open,  send = window.XMLHttpRequest.prototype.send,  onReadyStateChange;  function openReplacement(method, url, async, user, password) {  // some code   return open.apply(this, arguments); }  function sendReplacement(data) {  // some code   if(this.onreadystatechange) this._onreadystatechange = this.onreadystatechange;  this.onreadystatechange = onReadyStateChangeReplacement;   return send.apply(this, arguments); }  function onReadyStateChangeReplacement() {  // some code   if (this._onreadystatechange) return this._onreadystatechange.apply(this, arguments); }  window.XMLHttpRequest.prototype.open = openReplacement; window.XMLHttpRequest.prototype.send = sendReplacement;})();

这个解决方案,无法监听全部的 XHR Events ,而且 readystatechange 事件是在调用 send 方法后才监听,也就无法监听到 readyState = 1 时的事件。同时,如果在使用 send 方法后再对 onreadystatechange 设置回调函数,会将 override 的代码又一次 override,也就无法产生预想的效果。

 那如何才能正确地 override XHR 呢?贴上代码,一起来看看:

;(function() { function ajaxEventTrigger(event) {  var ajaxEvent = new CustomEvent(event, { detail: this });  window.dispatchEvent(ajaxEvent); }   var oldXHR = window.XMLHttpRequest;  function newXHR() {  var realXHR = new oldXHR();   realXHR.addEventListener('abort', function () { ajaxEventTrigger.call(this, 'ajaxAbort'); }, false);   realXHR.addEventListener('error', function () { ajaxEventTrigger.call(this, 'ajaxError'); }, false);   realXHR.addEventListener('load', function () { ajaxEventTrigger.call(this, 'ajaxLoad'); }, false);   realXHR.addEventListener('loadstart', function () { ajaxEventTrigger.call(this, 'ajaxLoadStart'); }, false);   realXHR.addEventListener('progress', function () { ajaxEventTrigger.call(this, 'ajaxProgress'); }, false);   realXHR.addEventListener('timeout', function () { ajaxEventTrigger.call(this, 'ajaxTimeout'); }, false);   realXHR.addEventListener('loadend', function () { ajaxEventTrigger.call(this, 'ajaxLoadEnd'); }, false);   realXHR.addEventListener('readystatechange', function() { ajaxEventTrigger.call(this, 'ajaxReadyStateChange'); }, false);   return realXHR; }  window.XMLHttpRequest = newXHR;})();            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选