JavaScript检测到一个AJAX事件
好吧,所以基本上我想要一个页面上的JavaScript,以某种方式附加某种全局事件侦听器,可以检测到并做一些事情,如果一个Ajax请求(不直接调用它从调用),而不pipeajax如何打电话。
我想通过jQuery的如何做到这一点 – 如果AJAX请求是由 jQuery完成的 。 这里是一个示例代码:
$.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,在页面加载,不pipe)。
不过,我希望能够扩展这个监听器来触发,而不pipe使用什么js框架,或者即使没有使用框架。 所以举例来说,如果我也在页面上有以下代码(来自w3schools的通用ajax代码):
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“全局事件侦听器”代码未能检测到该调用。
我做了更多的挖掘,我知道我基本上可以将对象保存到一个临时对象,并用一个“包装器”对象覆盖当前对象,该对象将调用指定的函数,然后调用临时函数,但这需要我知道时间是创build/使用的原始对象。 但是,我不会总是知道,提前…
所以……这可能吗? 有没有一些方法来检测ajax get / post请求,无论是使用通用对象还是xyz框架? 或者我只是将不得不做重复的代码来处理每个框架,并且也提前知道正在创build/使用的ajax对象?
编辑:
我忘记提及,发现请求是不够的。 我还需要捕获请求中发送的数据。 以下评论中提供的链接将有助于确定是否发出了“a”请求,但不能获取数据发送。 PS – 下面的链接提供的答案不是很清楚,至less对我来说反正。
好吧,这是我到目前为止:
<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>
方向:
只要把这个放在你的页面上,或者把它包含在一个.js文件或者其他的东西里。 这将创build一个名为s_ajaxListener的对象。 无论何时发出AJAX GET或POST请求,都会调用s_ajaxListener.callback(),并且可以使用以下属性:
s_ajaxListener.method :使用的ajax方法。 这应该是GET或POST。 注:该值可能不总是大写,这取决于如何编码特定的请求。 我在辩论智慧的自动上限,或把它留给别的东西toLowerCase()进行不区分大小写的比较。
s_ajaxListener.url :请求的脚本的URL(包括查询string,如果有的话)(urlencoded)。 我注意到,根据数据的发送方式以及浏览器/框架的不同,例如这个值最终可能是“”或“+”或“%20”。 我正在辩论在这里解码它的智慧,或者把它留给别的东西。
s_ajaxListener.data :发送的数据(如果有的话):foo = bar&a = b(与.url同样的“问题”,它被url编码)
笔记:
现在, 这不是IE6兼容 。 这个解决scheme对我来说不够好,因为我希望它是IE6兼容的。 但是因为很多其他人不关心IE6,我决定把我的解决scheme发布到目前的状态,因为如果你不关心IE6的话,它应该适合你。
我testing了这个 (截至这个发布date):目前的Safari浏览器,当前浏览器,当前火狐,IE8,IE8(IE7兼容)。 它目前不能用于IE6,因为IE6使用ActiveX对象,而几乎所有的东西都使用XMLHttpRequest。
现在我没有任何线索如何,以及基本上原型/扩展/重载(?)ActiveXObject(“Microsoft.XMLHTTP”)。 这是我目前正在研究的…有人知道吗?
在上面我testing过的每一个浏览器下面,这个对于来自一个通用对象的AJAX请求以及来自jquery和原型框架的AJAX请求都起作用。 我知道还有其他框架,但IMO这两个是主要的框架。 我可能会QA MooTools,但除此之外,我没事,只testing这些。
如果有人想通过testing和发布有关其他浏览器和/或框架的结果来贡献,那将不胜感激:)
对于IE 6的兼容性,如何:
<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>