$.ajaxPrefilter 与 $.ajaxTransport
14 Sep 2017jQuery 全局 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);
});