个人博客

A web front-end programmer's personal blog.

$.ajaxPrefilter 与 $.ajaxTransport

jQuery 全局 ajax 事件处理方法

在document任何元素上绑定事件处理器,方法有:

  • ajaxStart
  • ajaxSend
  • ajaxStop
  • ajaxSuccess
  • ajaxComplete
  • ajaxError

示例代码

$(document)
.ajaxStart(function(event, xhr, settings) {
    console.log('ajaxStart');
})
.ajaxSend(function(event, xhr, settings) {
    console.log('ajaxSend');
})
.ajaxStop(function(event, xhr, settings) {
    console.log('ajaxStop');
})
.ajaxSuccess(function(event, xhr, settings) {
    console.log('ajaxSuccess');
})
.ajaxComplete(function(event, xhr, settings) {
    console.log('ajaxComplete',settings);
})
.ajaxError(function(event, xhr, settings) {
    console.log('ajaxError');
});
$.ajax({
    url : 'http://localhost/Php/data.php',
    type : 'get',
    dataType : 'json',
    beforeSend : function(){
        console.log('data.php beforeSend');
    },
    success : function(){
        console.log('options success');
    }
}).done(function(res){
    console.log('data',res);
});

可以留意观察执行顺序

jQuery 底层处理接口 ajaxPrefilter 与 ajaxTransport

ajaxPrefilter 简单理解为在所有 ajax 请求send 之前调用做一些相应的处理,ajaxTransport简单理解为对请求(或某些类型的请求)进行改造处理

ajaxPrefilter的一个简单示例

$(document)
.ajaxStart(function(event, xhr, settings) {
    console.log('ajaxStart');
})
.ajaxSend(function(event, xhr, settings) {
    console.log('ajaxSend');
});

$.ajaxPrefilter(function(options,originalOptions,xhr){
    console.log('ajaxPrefilter',options);
    if (options.test) {
        console.log('option test');
    }

    if(options.success){
        options.realSuccess = options.success;  // 配置中的成功回调
        options.success = function(data){
            console.log(data,'change');
            options.realSuccess && (options.realSuccess(data));
        }
    }
});

$.ajax({
    url : 'http://localhost/Php/data.php',
    type : 'get',
    dataType : 'json',
    test : true,
    beforeSend : function(){
        console.log('data.php beforeSend');
    },
    success : function(){
        console.log('ajax suceess');
    }
}).done(function(res){
    console.log('data',res);
});

ajaxTransport 一个官方改造示例,将 json 类型的请求转换为图片类型,最后又返回json数据

var $ul = $('ul')
function show(data) {
	$ul.append('<li>' + data + '</li>');
}
// options 是请求的选项                                               
// originalOptions 值作为提供给Ajax方法未经修改的选项,因此,没有ajaxSettings设置中的默认值 
// jqXHR 是请求的jqXHR对象                                          
$.ajaxPrefilter("json", function(options, originalOptions, jqXHR) {
	//通过预处理器转化类型
	if (options.test) {
		options.type = 'GET'
	}
    if(options.success){
        options.success = function(data){
            console.log(data,'change');
        }
    }
	//增加前缀
	options.url = "http://img.mukewang.com/" + options.url
});
// 请求分发器 transports 
$.ajaxTransport("json", function(s) {
	if (s.type === "GET" && s.async) {
		var image;
		return {
			send: function(_, callback) {
                show('send')
				image = new Image();
				function done(status) {
					if (image) {
						var statusText = (status == 200) ? "success" : "error",
							tmp = image;
						image = image.onreadystatechange = image.onerror = image.onload = null;
						callback(status, statusText, {
                            // image : tmp,
							json: {'name':'blue'}
						},'application/json');
					}
				}
				image.onreadystatechange = image.onload = function() {
					done(200);
				};
				image.onerror = function() {
					done(404);
				};
				show(s.url)
				image.src = s.url;
			},
			abort: function() {
                show('abort')
				if (image) {
					image = image.onreadystatechange = image.onerror = image.onload = null;
				}
			}
		};
	}
});
$("#test").click(function(){
     //执行一个异步的HTTP(Ajax)的请求。
    var ajax = $.ajax({
		test     : true, //测试
		url      : '547d5a45000156f406000338-590-330.jpg',
		dataType : 'json',
		type     : 'POST',
        data: {
            foo: ["bar1", "bar2"]
        },
        //这个对象用于设置Ajax相关回调函数的上下文
        context: document.body,
        //请求发送前的回调函数,用来修改请求发送前jqXHR
        beforeSend: function(xhr) {
            xhr.overrideMimeType("text/plain; charset=x-user-defined");  //设置二进制文件类型
            show('局部事件beforeSend')
        },
        //请求完成后回调函数 (请求success 和 error之后均调用)
        complete: function() {
            show('局部事件complete')
        },
        error: function() {
            show('局部事件error请求失败时调用此函数')
        },
        success: function(res) {
            console.log('success',res);
            show('局部事件success')
        }
    })
    ajax.done(function(res) {
        console.log(res,'done');
        show('done')
    }).fail(function() {
        show('fail')
    }).always(function() {
        show('always')
    })
})

xhr.overrideMimeType 详情查看这里

ajaxPrefilter,ajaxTransport 与 localStorage 结合实现 ajax 缓存原理

  • ajaxPrefilter: 每次请求前检查是否有,没有的话在成功的回调中进行 localStorage 的存储

  • ajaxTransport: 将ajax请求拼成 localStorage 的 key , 相应数据JSON.stringify(data)为 value,每次请求检查是否已经有 key,wsCache为true,表示有,直接返回 localStorage中的值 JSON.parse(jsonstr)

	
	$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
        if (options.wsCache) {
            console.log('option wsCache');
        }
        if(options.success){
            options.realSuccess = options.success;
            options.success = function(data){
                console.log(data,'change');
                options.realSuccess && (options.realSuccess(data));
            }

        }
    });
    // +* 表示针对任何类型
    $.ajaxTransport('+*', function(options,originalOptions,xrh){
        console.log(options,'ajaxTransport');
        if(options.wsCache){ // localStorage 已经存过,不发请求(send函数无请求处理)直接返回结果
            return {
                send : function(headers,callback){
                    callback(200,'success',{json:{'name':'leo'}},'application/json');
                },
                abort : function(){

                }
            }
        }else{
            return;
        }

    });
    // wsCache 结合 localStorage 是否已经 存储过了
    $.ajax({
        url : 'http://localhost/Php/data.php',
        type : 'get',
        dataType : 'json',
        beforeSend : function(){
            console.log('data.php beforeSend');
        },
        wsCache : true, // false
        success : function(){
            console.log('ajax suceess');
        }
    }).done(function(res){
        console.log('data',res);
    });
    

相关文档