jQuery - 让ajax处理更强大

  • 作者:KK

  • 发表日期:2017.5.16


先展示一下我的ajax函数

通常在我带的项目里都会部署这个ajax函数:

function ajax(aOption){			
	var aUsingOption = $.extend({
		type : 'post',
		complete : function(oXhr){
			if(aOption.complete && aOption.complete(oXhr) === false){
				return;
			}
			
			if((oXhr.status >= 300 && oXhr.status < 400) && oXhr.status != 304){
				var redirectUrl = oXhr.getResponseHeader('X-Redirect');
				if(oXhr.responseText.length){
					alert(oXhr.responseText);
				}
				location.href = redirectUrl;
			}
		},
		error : function(oXhr){
			if(aOption.error && aOption.error(oXhr) === false){
				return;
			}
			
			if (oXhr.status === 0 && oXhr.readyState === 0) {
				console.error('请求中断,还没发出去啊亲,通常是快速切换页面时发生这种事');
				return;
			}
			if((oXhr.status >= 300 && oXhr.status < 400) && oXhr.status != 304){
				alert(oXhr.responseText);
			}
		}
	}, aOption);
	
	return $.ajax(aUsingOption);
}

//使用示例:
ajax({
	url : '/login.do',
	data : {
		account : 'abc',
		password : '121212',
	},
	success : function(result){}
});

其实就是把$.ajax包装了一层,使用这个包装后的ajax函数请求的时候,type默认是post,complete的时候会自动判断重定向(相关阅读《ajax不会自动重定向》的问题分析),还有error触发的时候只要不是重定向都会报出服务端的错误提示

这样的话如果用户的登录信息过期了,只要用的是这个ajax函数进行请求,那么当服务器检测到未登录返回重定向状态码的时候就可以自动跳转到登录页了

这个细节很重要,其实很多项目没处理这种问题,导致用户如果登录状态过期了的话,相关的ajax请求要么报错,要么没有任何相关处理代码导致没有反应


不提倡使用$.get和$.post

简单地说依然使用的话,会对少数情况下的控制需求造成一定影响

个别比较有经验的程序员会认为当页面初始化时执行$.ajaxSetup也可以实现代上面的ajax函数功能:

$.ajaxSetup({
	type : 'post',
	complete : function(oXhr){
		if((oXhr.status >= 300 && oXhr.status < 400) && oXhr.status != 304){
			var redirectUrl = oXhr.getResponseHeader('X-Redirect');
			if(oXhr.responseText.length){
				alert(oXhr.responseText);
				location.href = redirectUrl;
			}else{
				location.href = redirectUrl;
			}
		}
	},
	error : function(oXhr){
		if((oXhr.status >= 300 && oXhr.status < 400) && oXhr.status != 304){
			alert(oXhr.responseText);
		}
	}
});

这样就可以继续像往常一样用$.get$.post甚至$.ajax,而不必刻意使用另外包装的ajax

个人看法:没错这确实可以自动重定向、自动处理error,但是无法让$.ajax追加自己的completeerror回调,因为一旦声明这两个回调就会覆盖掉$.ajaxSetup里的completeerror两个属性,而我上面的ajax函数则不会覆盖(具体请看那两个=== false相关的判断处理)