前端这5个Ajax的坑,你踩过几个?别说都知道

谈到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对象装换成字符串即可。

如还有问题,你应该换个思路去考虑了,去运行下接口,比如我就碰到过一次,如下:

上图代码,是在CMS里做的一个接口,大家有没有看到问题所在了呢?其实是接口返回的根本不是一个完整的json呀;正常情况下,我们要去掉nextPage.....pageIndex,或者把两条数据外面包一层list,不应该吧下面的参数跟数据列表混在一起哦。于是在数据接口上做了处理优化,如下图的另外一个例子:

再运行下,果然正常了。

坑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中提交信息无效

关注私信回复“1”分享前端学习

这个问题可以说是无敌坑了,也是最近才发现的,近期做了一些活动,涉及到表单的提交。看段接口代码:

/**我的邀请奖励汇总记录接口**/
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"   
       }); 
   }

我自己是一名从事了多年的前端老程序员,小编为大家准备了新出的前端编程学习资料,免费分享给大家!

如果你也想学习前端,那么帮忙转发一下然后再关注小编后私信“01”可以得到我整理的这些前端资料了(私信方法:点击我头像进我主页有个上面有个私信按钮)



©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,589评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,615评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,933评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,976评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,999评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,775评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,474评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,359评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,854评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,007评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,146评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,826评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,484评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,029评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,153评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,420评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,107评论 2 356

推荐阅读更多精彩内容

  • AJAX 原生js操作ajax 1.创建XMLHttpRequest对象 var xhr = new XMLHtt...
    碧玉含香阅读 3,203评论 0 7
  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,105评论 1 32
  •   2005 年,Jesse James Garrett 发表了一篇在线文章,题为“Ajax: A new App...
    霜天晓阅读 893评论 0 1
  • 【转载】CSDN - 张林blog http://blog.csdn.net/XIAOZHUXMEN/articl...
    竿牍阅读 3,488评论 1 14
  • 一、简历准备 1、个人技能 (1)自定义控件、UI设计、常用动画特效 自定义控件 ①为什么要自定义控件? Andr...
    lucas777阅读 5,213评论 2 54