首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >JavaScript检测AJAX事件

JavaScript检测AJAX事件
EN

Stack Overflow用户
提问于 2010-08-30 05:04:40
回答 2查看 73.2K关注 0票数 80

好的,基本上我想在一个页面上有一些javascript,它以某种方式附加了某种全局事件侦听器,可以在发出ajax请求时检测并执行某些操作(而不是直接从调用中调用它),而不管ajax调用是如何进行的。

如果ajax请求是由jquery完成的,我想出了如何使用jquery来做到这一点。下面是一个示例代码:

代码语言:javascript
复制
$.post(
  // requested script
  'someScript.php', 
  // data to send
  {
    'foo' : 'bar',
    'a' : 'b'
  },
  // receive response
  function(response){
    // do something
  }
); // .post

// global event listener    
$(document).ajaxSend(
  function(event,request,settings){
    alert(settings.url); // output: "someScript.php"
    alert(settings.data); // output: "foo=bar&a=b"
  }
);

使用此代码,无论我在哪里/以何种方式调用$.post(..),全局事件侦听器都将触发。如果我使用$.get或$.ajax (任何jquery ajax方法),它也可以工作,无论我如何/何时调用它(作为onclick附加,在页面加载时,等等)。

但是,无论使用什么js框架,或者即使没有使用框架,我都希望能够将此侦听器扩展为触发器。因此,举个例子,如果我要在一个页面上有以下代码(来自w3schools的通用ajax代码):

代码语言:javascript
复制
function loadXMLDoc()
{
if (window.XMLHttpRequest)
  {// code for IE7+, Firefox, Chrome, Opera, Safari
  xmlhttp=new XMLHttpRequest();
  }
else
  {// code for IE6, IE5
  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
  }
xmlhttp.onreadystatechange=function()
  {
  if (xmlhttp.readyState==4 && xmlhttp.status==200)
    {
    document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
    }
  }
xmlhttp.open("GET","test.txt",true);
xmlhttp.send();
}

然后,我在某个随机链接上对该函数进行了onclick调用,我的全局ajax事件侦听器应该能够对此请求进行检测。我将该代码添加到我的页面,并将其附加到一个随机链接的onclick上(是的,代码本身可以工作),但是上面的jquery“全局事件侦听器”代码未能检测到该调用。

我做了更多的挖掘,我知道我基本上可以将对象保存到一个临时对象,并用一个“包装器”对象覆盖当前对象,该对象将调用指定的函数,然后调用临时函数,但这需要我提前知道正在创建/使用的原始对象。但我不会总是提前知道...

So...is这是可能的吗?有没有什么方法可以检测到ajax get/post请求的发出,不管它是通过通用对象还是来自xyz框架完成的?或者我只需要编写重复的代码来处理每个框架,并提前知道正在创建/使用的ajax对象?

编辑:

我忘了提一下,仅仅检测到请求的发生是不够的。我还需要捕获请求中发送的数据。下面评论中提供的链接将帮助确定是否发出了“请求”,但不会发送数据。附注:-下面的链接中提供的答案不是很清楚,至少对我来说是这样的。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-08-30 11:11:34

好的,这就是我到目前为止想出的:

代码语言:javascript
复制
<script type='text/javascript'>
var s_ajaxListener = new Object();
s_ajaxListener.tempOpen = XMLHttpRequest.prototype.open;
s_ajaxListener.tempSend = XMLHttpRequest.prototype.send;
s_ajaxListener.callback = function () {
  // this.method :the ajax method used
  // this.url    :the url of the requested script (including query string, if any) (urlencoded) 
  // this.data   :the data sent, if any ex: foo=bar&a=b (urlencoded)
}

XMLHttpRequest.prototype.open = function(a,b) {
  if (!a) var a='';
  if (!b) var b='';
  s_ajaxListener.tempOpen.apply(this, arguments);
  s_ajaxListener.method = a;  
  s_ajaxListener.url = b;
  if (a.toLowerCase() == 'get') {
    s_ajaxListener.data = b.split('?');
    s_ajaxListener.data = s_ajaxListener.data[1];
  }
}

XMLHttpRequest.prototype.send = function(a,b) {
  if (!a) var a='';
  if (!b) var b='';
  s_ajaxListener.tempSend.apply(this, arguments);
  if(s_ajaxListener.method.toLowerCase() == 'post')s_ajaxListener.data = a;
  s_ajaxListener.callback();
}
</script>

说明:

只需将其c/p放到您的页面上,或者将其包含在.js文件或其他文件中即可。这将创建一个名为s_ajaxListener的对象。每当发出AJAX GET或POST请求时,都会调用s_ajaxListener.callback(),并且以下属性可用:

s_ajaxListener.method:使用的ajax方法。这应该是GET或POST。注意:该值可能不总是大写的,它取决于特定请求的编码方式。我正在讨论自动大小写还是让toLowerCase()进行不区分大小写的比较是否明智。

s_ajaxListener.url:请求脚本的url (包括查询字符串,如果有)(url编码)。我注意到,根据发送数据的方式以及来自哪个浏览器/框架,例如,此值可能最终为“”或"+“或"%20”。我正在讨论在这里解码它是否明智,或者把它留给其他东西。

s_ajaxListener.data:发送的数据,如果有的话,ex: foo=bar&a=b (与.url相同的问题,因为它是url编码的)

备注:

现在看来,这不是IE6兼容的。这个解决方案对我来说还不够好,因为我希望它与IE6兼容。但是因为很多人都不关心IE6,所以我决定把我的解决方案放在它当前的状态下,因为如果你不关心IE6,它应该可以为你工作。

我已经在上测试过了(截止到现在):当前的Safari,当前的Chrome,当前的FireFox,IE8,IE8 (兼容IE7)。它目前不适用于IE6,因为IE6使用ActiveX对象,而几乎所有其他对象都使用XMLHttpRequest。

现在我不知道如何,嗯,基本上原型/扩展/重载(?)ActiveXObject("Microsoft.XMLHTTP")。这就是我目前所在的researching...does,有人知道吗?

在我上面测试的每个浏览器中,这都适用于来自通用对象的AJAX请求,以及来自jquery和prototype框架的AJAX请求。我知道还有其他的框架,但我认为这两个是主要的。我可能会使用QA MooTools,但除此之外,我只需要测试它们就可以了。

如果任何人想通过测试和发布关于其他浏览器和/或框架的结果来做出贡献,我们将不胜感激:)

票数 111
EN

Stack Overflow用户

发布于 2014-05-14 21:48:21

为了与IE 6兼容,下面的内容如何:

代码语言:javascript
复制
<script type='text/javascript'>
  var s_ajaxListener = new Object();

  // Added for IE support
  if (typeof XMLHttpRequest === "undefined") {
    XMLHttpRequest = function () {
      try { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }
      catch (e) {}
      try { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }
      catch (e) {}
      try { return new ActiveXObject("Microsoft.XMLHTTP"); }
      catch (e) {}
      throw new Error("This browser does not support XMLHttpRequest.");
    };
  }

  s_ajaxListener.tempOpen = XMLHttpRequest.prototype.open;
  s_ajaxListener.tempSend = XMLHttpRequest.prototype.send;
  s_ajaxListener.callback = function () {
    // this.method :the ajax method used
    // this.url    :the url of the requested script (including query string, if any) (urlencoded) 
    // this.data   :the data sent, if any ex: foo=bar&a=b (urlencoded)
  }

  XMLHttpRequest.prototype.open = function(a,b) {
    if (!a) var a='';
    if (!b) var b='';
    s_ajaxListener.tempOpen.apply(this, arguments);
    s_ajaxListener.method = a;  
    s_ajaxListener.url = b;
    if (a.toLowerCase() == 'get') {
      s_ajaxListener.data = b.split('?');
      s_ajaxListener.data = s_ajaxListener.data[1];
    }
  }

  XMLHttpRequest.prototype.send = function(a,b) {
    if (!a) var a='';
    if (!b) var b='';
    s_ajaxListener.tempSend.apply(this, arguments);
    if(s_ajaxListener.method.toLowerCase() == 'post')s_ajaxListener.data = a;
    s_ajaxListener.callback();
  }
</script>
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3596583

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档