旧的ajax请求对象:XmlHttpRequest
XmlHttpRequest在web开发中,已经有很长时间,在使用上面只要网页里牵涉到异步加载的,几乎都是使用XmlHttpRequest这个对象进行异步数据访问。由于时间长,所以各大浏览器/手机/pc等都对其api支持比较完善。以下是在项目中些的一个公共的ajax,这里备注以下
//这是最终执行ajax的方法,里面做了很多判断
var XmlHttpPost = function(data) {
try {
_appurl = data.serverInterface != undefined ? _interfaceAppUrl.format(data.serverInterface) : _appurl;
} catch(e) {
//TODO handle the exception
}
var ajaxData = {
type: "post",
contentType: data.contentType ? data.contentType : "application/json;charset=utf-8",
async: data.sync ? data.sync : false,
timeout: data.timeout ? data.timeout : 5000,
url: data.url ? data.url : _appurl,
dataType: data.dataType ? data.dataType : 'json',
data: data.data ? data.data : "",
jsonp: data.jsonp ? data.jsonp : "weicyjsoncallback",
success: data.success ? data.success : function(result) {
if(_AppDebug) {
console.log(result)
}
},
complete: data.complete ? data.complete : completeDefault,
error: data.error ? data.error : function(er) {
try {
mui.toast("访问出错,请检查网络连接");
} catch(e) {
//TODO handle the exception
alert("访问出错");
}
}
};
excFunctionAjax(ajaxData);
}
var excFunctionAjax = function(ajaxData) {
var next = GetUrlRelativePath(); //获取房钱的url
var first = GetUrlRelativePath(ajaxData.url);//获取ajaxData对象传入的url
//如果不是jsonp,并且域名不相同,或者链接里面域名为null,则进行普通的ajax请求
if((ajaxData.dataType != 'jsonp') || (first.domain == next.domain) || first.domain == "") {
//判断地址是否有效,若无效
if(ajaxData.dataType == 'jsonp') {
ajaxData.dataType = "json";
}
if(!tools.Kit.isURL(ajaxData.url)) {
//地址无效,判断配置是否是tomcat根目录,若是,则进行if,否则进行else
if(Kit_Config.isRoot) {
ajaxData.url = next.httpType + next.domain + ajaxData.url;
} else {
ajaxData.url = next.httpType + next.domain + Kit_Config.webProject + ajaxData.url;
}
} else { //若是有效域名,则对域名进行相应的封装请求
//ajaxData.url = next.httpType+next.domain+first.url;
}
//进行ajax请求
if(_AppDebug) {
console.log(ajaxData.type + "请求的url:" + ajaxData.url);
}
//alert("ajax+++"+JSON.stringify(ajaxData));
$.ajax({
type: ajaxData.type,
url: ajaxData.url,
data: ajaxData.data,
contentType: ajaxData.contentType || "application/x-www-form-urlencoded; charset=UTF-8",
headers: {
"openid": localToken[0],
"token": localToken[1],
'url': window.location.href
},
dataType: "text",
success: function(data) {
if(ajaxData.type == "GET" || ajaxData.type == 'get'){
data = data.replace(/:\s\d{18}/g, ":\"@!#@!#$&\"").replace(/:\d{18}/g, ":\"@!#@!#$&\"").replace(/@!#@!#:\s/g,"").replace(/@!#@!#:/g,"");
}
data = JSON.parse(data);
ajaxData.success(data);
},
complete: function(XMLHttpRequest, status) {
ajaxData.complete(XMLHttpRequest, status);
},
error: function(er) {
console.log(er);
ajaxData.error(er);
}
});
} else {
//不用验证,直接进行ajax请求
$.ajax({
type: ajaxData.type,
url: ajaxData.url,
dataType: "text", //上面ajaxData中已经传入了相应的dataType格式,但是这里直接写死是因为项目中有一个需求,会返回一个很长的Long类型的数据,如果按照json传递过来,在ajax内部会使用JSON.parse()进行转换,这样由于服务器的long和javascript的long位数不同,所以会造成溢出。所以最终得到的long并非服务器的long,而是截取之后的long。网上有一个bigint的js库,但是只适用于单个数据,服务器传递过来又不可能是单个数据,所以这里直接以文本方式进行接送,然后本地通过正则表达式进行处理。
data: ajaxData.data,
headers: {
"openid": localToken[0],
"token": localToken[1],
'url': window.location.href
},
contentType: ajaxData.contentType || "application/x-www-form-urlencoded; charset=UTF-8",
success: function(data) {
if(ajaxData.type == "GET" || ajaxData.type == 'get'){//只转换get请求的,因为post请求的一般不会返回很长的数据。如果项目有需求可以释放这里为全部,这里只是将等于18位的给转换了
data = data.replace(/:\s\d{18}/g, ":\"@!#@!#$&\"").replace(/:\d{18}/g, ":\"@!#@!#$&\"").replace(/@!#@!#:\s/g,"").replace(/@!#@!#:/g,"");
}
data = JSON.parse(data);//因为得到的是text文本,所以这里要将文本转换为json对象传递给外部使用
ajaxData.success(data);
},
complete: function(XMLHttpRequest, status) {
ajaxData.complete(XMLHttpRequest, status);
},
error: function(er) {
console.log(er);
ajaxData.error(er);
}
});
}
}
var GetUrlRelativePath = function(relUrl) {
var url = relUrl || window.location.href.toString();
if(!tools.Kit.isURL(url)) {
var urlPath = {
httpType: "", //返回http方式
domain: "", //返回域名
url: url //返回url地址
};
return urlPath;
} else {
var arrUrl = url.split("//");
var start = arrUrl[1].indexOf("/");
var domain = arrUrl[1].substring(0, start);
var relUrl = arrUrl[1].substring(start); //stop省略,截取从start开始到结尾的所有字符
// if(relUrl.indexOf("?") != -1){
// relUrl = relUrl.split("?")[0];
// }
var urlPath = {
httpType: arrUrl[0] + "//", //返回http方式
domain: domain, //返回域名
url: relUrl //返回url地址
};
return urlPath;
}
}
上面就是xmlhttprequest的自己的封装,当时包含了跨域自动判断,但是由于项目不需要(使用服务器的corse),所以删除了。【注意,ajax jsonp只支持get,因为它是通过将服务器数据封装了一个javascript代码,引用javascript是不用考虑跨域的这样解决的】
新的ajax请求对象:fetch
因为新的fetch 在浏览器的支持还不是太完善【pc基本完全支持,手机端主要表现在iphone6s 以下的机型】,主要表现为,机型支持fetch,但是支持的不完全,就会导致有一些地方会出现莫名其妙的错误。大部分浏览器能够访问到后台,但是后台传递过来的数据在前端解析就会出现类型错误TypeError等问题
var fetchPost = function(data) {
try {
_appurl = data.serverInterface != undefined ? _interfaceAppUrl.format(data.serverInterface) : _appurl;
} catch(e) {
//TODO handle the exception
}
var _postData = new FormData();
_postData.append("json", data.data || "");
/*
try {
let response = await fetch(data.url || _appurl,{method: "POST",body:_postData});
let _dataAwait = await response.json();
console.log(_dataAwait);
return _dataAwait;
} catch(e) {
console.log("Oops, error", e);
}
*/
fetch(data.url || _appurl, {
method: "POST",
headers: {
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Content-Type': 'application/json;charset=UTF-8',
'openid': localToken[0],
'token': localToken[1],
'url': window.location.href
},
body: data.data
}).then(function(rsp) {
if(rsp.ok) {
//console.log(response);
//data.success(rsp.json());
//console(BigInteger(res.json())+"+++");
return rsp.json();
} else {
console.log("error fetch");
}
}).then(function(dataJSON) {
data.success(dataJSON);
if(_AppDebug) {
console.log("POST地址:" + data.url || _appurl);
console.log("debug======:" + JSON.stringify(dataJSON));
}
}).catch(function(e) {
if(_AppDebug) {
console.log("POST地址:" + data.url || _appurl);
console.log("debug====:error ajax " + e);
}
try {
//alert("错误日志:"+e);
mui.toast("访问出错,请检查网络连接");
} catch(e) {
//TODO handle the exception
alert("访问出错");
}
})