ajax long 不对,ajax 请求long数据溢出的转换问题以及fetch api兼容性问题

旧的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("访问出错");

}

})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值