博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
这5个Ajax的坑,你踩过几个?
阅读量:4117 次
发布时间:2019-05-25

本文共 7132 字,大约阅读时间需要 23 分钟。

640?wx_fmt=jpeg
谈到ajax,大家都不会陌生,对于 Web前端 开发的童鞋,经常会跟它打交道,难免入"坑"。 今天来分享下 前端开发 遇到的问题; 首先,还是了解下 ajax 的定义。

ajax()定义

ajax() 方法通过 HTTP 请求加载远程数据。
该方法是 jQuery 底层 ajax 实现。 简单易用的高层实现见 $.get, $.post 等。 $.ajax()返回其创建的XMLHttpRequest 对象。
大多数情况下你无需直接操作该函数,除非你需要操作不常用的选项,以获得更多的灵活性。
最简单的情况下,$.ajax() 可以不带任何参数直接使用。
注意:
所有的选项都可以通过 $.ajaxSetup() 函数来全局设置。
了解完 ajax() 的定义,直接进入主题吧,脱坑时间走起。

坑1:jQuery+ajax提交json数据成功却进入error

我们还是拿一段自己写的一段代码来解析下,什么时候出现这个情况,如下:
function getNews(){	try{	        $.ajax({	type: "GET",	url:'xxx.json',	dataType: 'json',	jsonp : "callback",	success: function (msg) {	console.log(msg); 	            },	error:function (error) {	console.log(error)	            }	        });	    }catch(e){	        alert(e.message);	return false;	    }	}
定义一个函数,然后使用try...catch, 在浏览器里走一波吧。 咦? 怎么就是进不了success,一直都是打印的error错误信息。
此时此刻,会怀疑这个ajax调用代码有问题,各种调改,后面发现还是问题依旧; 如果您真正的跳进了这个坑,在ajax代码没问题的情况下,首先考虑数据类型。
首先得确保json的jar包都已经导入正确
然后在看看网页和servlet之间的数据类型是否一致
contentType: "application/json;charset=utf-8",两边都需要设置一下传输的内容
如果遇到将数据发送到网页端显示 undefined 或者object Object时,用JSON.stringify(data)将该json对象装换成字符串即可。
如还有问题,你应该换个思路去考虑了,去运行下接口,比如我就碰到过一次,如下:
640?wx_fmt=jpeg
上图代码,是在CMS里做的一个接口,大家有没有看到问题所在了呢? 其实是接口返回的根本不是一个完整的json呀; 正常情况下,我们要去掉nextPage.....pageIndex,或者把两条数据外面包一层list,不应该吧下面的参数跟数据列表混在一起哦。 于是在数据接口上做了处理优化,如下图的另外一个例子:
640?wx_fmt=png
再运行下,果然正常了。
坑2: jQuery+ajax同步和异步问题
关于同步和异步问题,是很常见的,不同域名调用不同地址的接口,就会遇到此类问题。
同步: 提交请求->等待服务器处理->处理完毕返回 这个期间浏览器不会做任何事
异步: 请求通过事件触发->服务器处理(这是浏览器仍然可以作其他事情)->处理完毕
同步就是你叫我去吃饭,我听到后就跟你去吃饭; 如果没有听到,你就不停的叫,直到我告诉你听到了,才一起去吃饭。
异步就是你喊了我一声去吃饭,然后自己就先走了去吃饭,我得到消息后可能马上追着你去吃饭,也可能等到下班后我自己再去吃饭。
所以,要我请你吃饭就用同步的方法,要请我吃饭就用异步的方法,这样你可以省钱。
举个生活中的例子: 打电话时同步,发消息就是异步。
看看open方法的几个参数。
.open (http-method, url, async, userID, password)	(后面是帐号和密码,在禁止匿名访问的http页面中,需要用户名和口令)
首先看看异步处理方式:
其中async是一个布尔值。 如果是异步通信方式(true),客户机就不等待服务器的响应; 如果是同步方式(false),客户机就要等到服务器返回消息后才去执行其他操作。
我们需要根据实际需要来指定同步方式,在某些页面中,可能会发出多个请求,甚至是有组织有计划有队形大规模的高强度的request,而后一个是会覆盖前一个的,这个时候当然要指定同步方式: Flase。
请求方式
分为GET与POST: GET 最为常见的HTTP请求,普通上网浏览页面就是GET。 GET方式的参数请求直接跟在URL后,以问号开始。 (JS中用window.location.search获得)。 参数可以用encodeURIComponent进行编码,使用方式:
var EnParam = encodeURIComponent(param);
URL只支持大约2K的长度,即2048字符数; 使用GET进行AJAX请求时候会缓存导致出现的页面不是正确的,一般方法加random参数值; ajax.send(null)。
POST - 向服务器提交数据用到。 需要将form表单中的值先取出转换成字符串,用&符号连接,(同GET传参数一样); 提交数据量2GB ; 使用ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'),处理提交的字符串;ajax.send(strings),这个strings表示form中需要提交的内容,例如a=1&b=2类似这样的字符串。
同步与异步
ajax.open方法中,第3个参数是设同步或者异步。 prototype等js类库一般都默认为异步,即设为true。 先说下同步的情况下,js会等待请求返回,获取status。 不需要onreadystatechange事件处理函数。 而异步则需要onreadystatechange事件处理,且值为4再正确处理下面的内容。   
坑3:
ajax中,当async为false时,同步操作失败
遇到这个问题也是醉了,说明你对于ajax还是不够了解哦,来段原始代码分析分析,如下:
$.ajax({	    url : 'your url',	    data:{name:value},	    cache : false, 	async : true,	type : "POST",	    dataType : 'json/xml/html',	    success : function (result){	return result;	    }	});

原因就是错误使用了return,我试着修改下:
var ret = null;	$.ajax({	    url : 'your url',	    data:{name:value},	    cache : false, 	async : true,	type : "POST",	    dataType : 'json/xml/html',	    success : function (result){	        ret=result;	    }	});	return ret;
说明:
不要在success的回调函数中直接return。

坑4:jQuery+ajax在手机Safari中提交信息无效

这个问题可以说是无敌坑了,也是最近才发现的,近期做了一些活动,涉及到表单的提交。 看段接口代码:
/**我的邀请奖励汇总记录接口**/	getTotalList:function(v){	try{	var al = "#firstAnchor";	            $.ajax({	url:getOAByActivity()+"/act/se/20190916/recommend/my/total",	dataType:"jsonp",	jsonp:"callback",	data:{activityPeriods:"SE20190916",companyId:"14"},	success:function(msg){                    	var code = msg["code"];	if("0"==code){	                        执行1	                    }else if("98"==code || "99"==code){	                        执行2	                    }	else{	                        alert("网络问题"+code);	                    }	                }	            });	    }	catch(e){	        alert(e.message);	    }	}
最开始的代码是这样的,记录接口需要用户的账号、手机号码以及data的变量才能执行,这个函数调用会在登录判断无问题且成功调用登录接口后执行。登录调用代码如下:
//提交注册数据	submitLogin:function(event){	//var _this=event.data.obj;	try{	        $(".error_msg").html("").hide();	//验证数据	var accountNo=$.trim($("#accountNo").val());	if(accountNo=='' || accountNo.length<6){	            $(".error_msg").html("请输入正确的账户号码").show();	//alert("请输入正确的账户号码");	return false;	        }	if('90' == accountNo.substr(0, 2)){	            $(".error_msg").html("账户类型暂不支持").show();	//alert("账户类型暂不支持");	return false;	        }	var phoneNo=$.trim($("#guestPhone").val());	var regPhone = /^(13|14|15|16|17|18|19)\d{9}$/;	if (!regPhone.test(phoneNo)){	            $(".error_msg").html("请输入正确的手机号码").show();	//alert("请输入正确的手机号码");	return false;	        }		//ajax	        $.ajax({	type:"POST",	url: getOAByActivity()+"/act/ext/login",	dataType:"jsonp",	jsonp:"callback",	data:{activityPeriods:"SE20180916",accountNo:accountNo,phone:phoneNo,captchaFlag:"0",companyId:"14"},	success:function(msg){	if("0"==msg["code"]){//成功	                    $("#member_login").hide();	                    recommend.getTotalList(1);	                    $("#login_false1").hide();	                    $("#login_false2").hide();	                }else if (msg["code"] == '20063'){	                    $(".error_msg").html("很抱歉,您还没有开通/激活真实账户,请先开通/激活账户,如有疑问请咨询在线客户!").show();	                }else{	                    $(".error_msg").html(msg["infoMsg"]).show();	//alert(msg["msg"]);	return false;	                }	            }	        });		    }	catch(e){	        alert(e.message);	return false;	    }	}
按照正常逻辑,执行login接口后,浏览器已经记录了用户的信息,但发现在PC端浏览器,移动端QQ、UC、谷歌等,返回code=0,都测试正常;但是在苹果自带Safari浏览器里返回code=20019,未登录状态。
此时也蒙蔽了,后面也折腾了下解决方案,其实我们还需要在“记录”接口里,再次定义获取用户的账号和手机号:
var accountNo=$.trim($("#accountNo").val());	var phoneNo=$.trim($("#guestPhone").val());
完整代码:
/**我的邀请奖励汇总记录接口**/	getTotalList:function(v){	var accountNo=$.trim($("#accountNo").val());	var phoneNo=$.trim($("#guestPhone").val());	try{	var al = "#firstAnchor";	            $.ajax({	url:getOAByActivity()+"/act/se/20190916/recommend/my/total",	dataType:"jsonp",	jsonp:"callback",	data:{activityPeriods:"SE20190916",companyId:"14"},	success:function(msg){                    	var code = msg["code"];	if("0"==code){	                        执行1	                    }else if("98"==code || "99"==code){	                        执行2	                    }	else{	                        alert("网络问题"+code);	                    }	                }	            });	    }	catch(e){	        alert(e.message);	    }	}
这样才会正常,说实话,遇到这个问题,也是醉了。

坑5:jQuery+ajax在手机Safari中无法执行
这个坑,可能少见,但是还是要说说,还是以代码为例子:
$.ajax({  	type: "POST",  	    url: "http://www.xxx.com/xxx.jsp",  	    data: "nick_name=nickname&newsid=nid&content=content&callback=?",  	    dataType : "jsonp"	});
在safari下jsp页面接收不到数据,加上参数( async: false),去掉(dataType : "jsonp")safari可以了,但ie又不行了,ie少了( dataType : "jsonp")不行,没办法只有判断浏览器了,safari单独处理为:
var sUsrAgent=navigator.userAgent;  var isSF=sUsrAgent.indexOf("Safari")!=-1;  if(isSF){      $.ajax({  type: "POST",          url: "http://xxxxxx.jsp",          data: "nick_name=nickname&content=content&callback=?",  async: false    });  }else{      $.ajax({  type: "POST",          url: "http://xxxxxx.jsp",          data: "nick_name=nickname&content=content&callback=?",  async: false,          dataType : "jsonp"    });  }

640?wx_fmt=jpeg
640?wx_fmt=png

转载地址:http://sffpi.baihongyu.com/

你可能感兴趣的文章
关于不同的编译器使用过程中遇到的问题!
查看>>
关于C和C++,还有c#,还有java程序的速度问题!
查看>>
关于C和C++,还有c#,还有java程序的速度问题!(二)
查看>>
关于C和C++,还有c#,还有java程序的速度问题!(三)
查看>>
关于C和C++,还有c#,还有java程序的速度问题!(四)
查看>>
【商城】redis分布式多级缓存应用(瓶颈之殇)
查看>>
分布式缓存一致性问题方案
查看>>
【商城】redis分布式缓存更新应用(击穿问题)
查看>>
【商城】redis分布式缓存安全应用(穿透问题)
查看>>
【商城】redis大厂实战应用场景(一览众山小)
查看>>
【商城】canal数据库数据实时同步利器
查看>>
【商城】Elasticsearch搜索引擎
查看>>
【商城】Minio+ImgProxy商城图片一站式处理
查看>>
【数据平台】之Cassandra大数据利器
查看>>
【数据平台】之Cassandra大数据利器-代码实战干货I
查看>>
【数据平台】之Kafka+Minio数据埋点大数据利器
查看>>
【数据平台】之Alluxio内存加速大数据利器
查看>>
【数据平台】之Cassandra大数据利器-大规模数据迁移sstableloader
查看>>
【商城】canal数据库数据实时同步利器-代码实战干货
查看>>
【商城】Elasticsearch搜索引擎-01.构建搜索系统之查询-实战
查看>>