用javascript监听页面上的所有ajax请求

最近碰到一个很纠结的技术问题。

我们自己是个Grails,集成了另外一个web程序,我们把那个web程序放在我们提供的iframe里。那个web程序只有在第一次初始化的时候是一个普通的HTTP请求,之后在页面上的操作,都是通过ajax来操作的。现在我们有个需求,我们需要知道iframe里面做了什么操作。

没法改别人的代码,那我们只能监测里面的事件了,所以总归来说,要找到一种方法来检测到iframe里面的所有ajax请求。

Javascript框架熟悉的就只有JQuery,所以第一个想到的是用JQuery,看看有没有提供什么方法。找到了,JQuery确实提供了监听ajax的工具方法,如:

$("#msg").ajaxComplete(function(event,request, settings){
   $(this).append("<li>请求完成.</li>");
 });
这个方法会在所有ajax请求完成后被调用。

再深入找资料,想知道这个方法的原理,发现,原来JQuery提供的监听ajax的方法,只对本身就是用JQuery发出去的请求才有效。原理上也就简单了,在JQuery自己的代码里插入一些控制就实现了。

继续查资料,终于在stackoverflow找到了答案:用来发送ajax的对象XMLHttpRequest本身自己就是一个javascript对象(IE6除外),javascript对象就一定有prototype属性,有这个属性,那我就可以改这个属性的内容。

prototype属性是什么东西,我们这里没法详细描述,简单描述一下就是:我们可以用这个熟悉来修改对象,给对象添加/修改属性或者方法

接下来就和javascript实现继承一样了,我们要做的就是合理的修改XMLHttpRequest的open,send子类的方法,嵌入我们自己的callback代码,即可实现对所有ajax请求的监听。 

封装stackoverflow上的代码,写了一个工具类,代码如下:

function ajaxSend(objectOfXMLHttpRequest, callback) {
	// http://stackoverflow.com/questions/3596583/javascript-detect-an-ajax-event
	if(!callback){
		return;
	}
	
	var s_ajaxListener = new Object();
	s_ajaxListener.tempOpen = objectOfXMLHttpRequest.prototype.open;
	s_ajaxListener.tempSend = objectOfXMLHttpRequest.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)
		callback(this.method, this.url, this.data);
	}
	
	objectOfXMLHttpRequest.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];
		}
	}
	
	objectOfXMLHttpRequest.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();
	}
}

这个工具方法输入两个参数:

第一个参数是要监听的页面里的XMLHttpRequest对象

第二个参数是一个回调function,回调funtion接收三个参数,分别是

        method :ajax请求的方法,Get,Post,Put之类
        url :请求的URL
        data :请求的数据

看回工具方法的实现,实现原理就是也简单:

第一步:把XMLHttpRequest自身的open,send方法保存起来,存在临时变量里

第二步:修改open方法,新的open方法先调用第一步存起来的XMLHttpRequest自身的open方法,然后把请求时的参数保存到一些变量里以备后面用

第三步:修改send方法,新的send方法先调用第一步存起来的XMLHttpRequest自身的send方法,然后调用callback方法,callback的参数就是在第二步存起来的那些open时候的参数

最后,对于我们自己来说,就是把上面的代码加到iframe上了,

第一步:写一个callback,类似这样:

function onAjaxSend(method, url, data) {
}
第二步:设置iframe的onload属性为onload="ajaxSend(this.contentWindow.XMLHttpRequest, onAjaxSend);"


完工,不足的地方是不支持IE6,好在我们本身就不要对IE6提供支持,也就这样过了


参考资料:http://stackoverflow.com/questions/3596583/javascript-detect-an-ajax-event


关键字:Javascript,ajax,监听请求


你可能感兴趣的:(Ajax)