原生js实现AJAX(三)
为了实现如jQuery的AJAX一样的对请求中的data进行处理一样的功能,需要对上一篇的博客中的ajax方法进行一定的改进,比如对data类型进行判断,再根据判断结果进行编码,所以就需要如下所示的代码:
/*对AJAX的data数据进行编码*/
u.encodeData=function(data) {
if(!data) return '';
if(typeof data=='string') return data;
var pairs=[],i,len;
if(u.isObject(data)) {
for(var name in data) {
if(!data.hasOwnProperty(name)) continue;
var value=data[name].toString();
name=encodeURI(name);
value=encodeURI(value);
pairs.push(name+'='+value);
}
return pairs.join('&');
}
if(u.isArray(data)) {
for(var i=0,len=data.length;i<len;i++) {
pairs.push(encodeURI(data[i].name)+'='+encodeURI(data[i].value));
}
return pairs.join('&');
}
return new Error('数据不符合格式');
};
/*判断数据类型是否为数组*/
u.isArray=function(o) {
return typeof o=='object'&&Object.prototype.toString.call(o).slice(8,-1).toLowerCase()=='array';
}
/*判断数据类型是否为对象*/
u.isObject=function(o) {
return typeof o=='object'&&Object.prototype.toString.call(o).slice(8,-1).toLowerCase()=='object';
}
有了这些函数以后,就可以对data进行编码,进行ajax请求时就可以使用多种类型的data,而不必拘泥于格式。
完整的代码如下所示:
var u=window.u||{};
u.createXHR=function() {
var methods=[
function() {return new XMLHttpRequest();},
function() {return new ActiveXObject(Msxml2.XMLHTTP);},
function() {return new ActiveXObject(Microsoft.XMLHTTP);}
];
for(var i=0;i<3;i++) {
try {
methods[i]();
} catch(e) {
continue;
}
this.createXHR=methods[i];
return methods[i]();
}
throw new Error("没有找到XHR对象");
};
/*对AJAX的data数据进行编码*/
u.encodeData=function(data) {
if(!data) return '';
if(typeof data=='string') return data;
var pairs=[],i,len;
if(u.isObject(data)) {
for(var name in data) {
if(!data.hasOwnProperty(name)) continue;
var value=data[name].toString();
name=encodeURI(name);
value=encodeURI(value);
pairs.push(name+'='+value);
}
return pairs.join('&');
}
if(u.isArray(data)) {
for(var i=0,len=data.length;i<len;i++) {
pairs.push(encodeURI(data[i].name)+'='+encodeURI(data[i].value));
}
return pairs.join('&');
}
return new Error('数据不符合格式');
};
u.isArray=function(o) {
return typeof o=='object'&&Object.prototype.toString.call(o).slice(8,-1).toLowerCase()=='array';
}
u.isObject=function(o) {
return typeof o=='object'&&Object.prototype.toString.call(o).slice(8,-1).toLowerCase()=='object';
}
u.ajax=function(options) {
var method=options.method.toUpperCase()||'GET',
url=encodeURI(options.url),
success=options.success,
failed=options.failed,
data=options.data||null,
file=options.file||false;
var xhr=u.createXHR();
if(!file) {
if(method=='GET') {
url+='?'+u.encodeData(data);
data=null;
} else {
data=u.encodeData(data);
}
}
xhr.open(method,url,true);
xhr.onreadystatechange=function() {
if(xhr.readyState==4) {
if((xhr.status>=200&&xhr.status<300)||xhr.status==304) {
success(xhr.responseText);
xhr=null;
}
} else {
if(xhr.status!=200) {
failed(xhr.status);
}
}
}
if(!file) {
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
}
xhr.send(data);
}
在程序的参数中存在一个file ,该参数表示data是否存在文件对象,当需要在AJAX请求中包含文件时,可使用XHR2的FormData API。利用FormData将文件包含在data中,同时设置file参数为true,即可在ajax请求中包含文件。
该方法的缺陷是只有在支持XHR2的浏览器才可实现,存在一定的兼容性问题。