xiaotutu6000
xiaotutu6000
  • 发布:2018-04-20 09:27
  • 更新:2018-04-27 15:18
  • 阅读:1679

【报Bug】mui.ajax 隔一天不用后,前三次左右请求会超时。但是在手机上,重试几次后,就可以了。

分类:HTML5+

详细问题描述
[内容]
mui.ajax 隔一天不用后,前三次左右请求会超时。但是在手机上,重试几次后,就可以了。

-->在iphone 和 安卓机上,都会出现这样的情况。

    1. 在网页上请求是没有问题。
  • --> 问题已解决,在请求的url后面,加一个时间戳,保证每次请求的url地址不一样即可。但是在程序中如何取消这个缓存判断,不知道怎么弄。
  • - --> 又出现了。感觉超时设置的描述没起作用一样。直接报错,后台没有收到任何消息。但是我在浏览器上访问同一个地址。又能够立马返回结果。

  • 请求的url。看日志反应,是有链接上服务器,都进入到请求中。但是请求中,之后,就立马返回。服务器任何日志都没有产生。如果在出现这个问题的同时,去浏览器访问。是能够正常返回的。
  • 
    [LOG] : ----> http://www.hoyob.com/csck/sjbAutoLogin?ts=Sat Apr 21 2018 21:29:18 GMT+0800 (CST)  

[LOG] : ssssssssssssssssssssssssssssssssssssssssssssssss请求中

[LOG] : ---- login.html ----> _shopLoginAutoLogin -> apply ## error ##:
[LOG] : mui.ajax xhr error is {}
[LOG] : mui.ajax type error is timeout
[LOG] : mui.ajax errorThrown error is null
[LOG] : ------>自动登陆重复标识 10
[LOG] : ssssssssssssssssssssssssssssssssssssssssssssssss请求结束timeout |

-- 重写了请求方法,在等一两天测试下。(经过一天一晚的验证,重新ajax请求,基本不会再出现类似问题。)  
- 
```javascript  

    var xhr = new plus.net.XMLHttpRequest();  

    xhr.open( 'POST', 'http://'+ DKJALLHOST +'/csck/' + interfaceName + '?ts='+Date.parse(new Date()) , true );  

    xhr.setRequestHeader('accept','application/json');  
    xhr.setRequestHeader('Content-Type','application/json');  
    xhr.setRequestHeader('accept-encoding' , 'gzip, deflate');  
    xhr.setRequestHeader('accept-language' , 'zh-CN,en-US;q=0.9');  
    xhr.setRequestHeader('origin' , 'file://');  
    xhr.setRequestHeader('x-requested-with' , 'XMLHttpRequest');  

    xhr.timeout = 10000;  
    xhr.responseType = "json";  

    xhr.onreadystatechange = function(){  
        switch ( xhr.readyState ) {  
            case 0 : { console.log( "xhr请求已初始化" ); break; }  
            case 1 : { console.log( "xhr请求已打开" ); break; }  
            case 2 : { console.log( "xhr请求已发送" ); break; }  
            case 3 : { console.log( "xhr请求已响应"); break; }  
            case 4 : {  
                if ( xhr.status == 200 ) {  
                    console.log( "xhr请求成功:"+xhr.responseText );  
                } else {  
                    console.log( xhr.status + "xhr请求失败:"+xhr.readyState );  
                }  
                break;  
            }  
            default :{  
                console.log('未知错误!'); break;  
            }  
        }  
    }  
    xhr.onload = function(e){   
        console.log( 'xhr请求成功事件处理' );  
        var str="lengthComputable="+e.lengthComputable+"loaded="+e.loaded+";total="+e.total;  
        console.log("onload: "+str);  

        console.log('后端返回数据返回数据 '+ this.responseText );  

        if(this.status == 200||this.status == 304){  

            if( callback ){  
                callback( JSON.parse( this.responseText ,true ) );  
            }  
            return ;  
        }  

    }  

    xhr.send( JSON.stringify(data) );
  • 重现步骤
    [步骤] app 隔一天不使用
    [结果] 初次登录返回,很快返回超时。
    [期望]

运行环境
[系统版本] linux centos 6.5
[浏览器版本] 手机APP
[IDE版本] HBuilder 9.0.2.201803061935
[mui版本] Mui v3.6.0 (http://dev.dcloud.net.cn/mui)

附件
[代码片段]

[安装包]

联系方式
[QQ]
[电话]

2018-04-20 09:27 负责人:无 分享
已邀请:
DCloud_UNI_FXY

DCloud_UNI_FXY

mui.ajax 大部分情况下使用的是window.XMLHttpRequest
get请求会有缓存,可以使用mui.ajax(url,{cache:false})来禁用缓存,cache 为 false 后,mui 的 ajax 请求会在 url 后自动追加一个时间戳参数来避免缓存
plus.net.XMLHttpRequest 仅在需要跨域访问时才会启用。plus.net.XMLHttpRequest不存在缓存问题

  • xiaotutu6000 (作者)

    我是用的post请求,缓存的我也想到的了。URL我都加了时间戳。

    2018-04-26 12:28

  • DCloud_UNI_FXY

    回复 xiaotutu6000:你可以把你代码中的 plus.net.XMLHttpRequest换成 window.XMLHttpRequest,然后测试是否还有此问题。如果也没问题,那可能是 mui 的 ajax 代码问题。

    2018-04-26 12:30

  • xiaotutu6000 (作者)

    回复 DCloud_UNI_FXY:好我下午试下。 提示:jquery 的ajax 也有同样的问题。

    2018-04-26 12:31

  • DCloud_UNI_FXY

    回复 xiaotutu6000:另外还可以看看出问题的时候,服务端返回的 response 的 状态码

    2018-04-26 12:32

  • xiaotutu6000 (作者)

    回复 DCloud_UNI_FXY:我按要求改了代码。response 返回的不是状态码,直接是我要返回结果文本。不过是可以调通的。

    2018-04-26 14:31

  • xiaotutu6000 (作者)

    回复 DCloud_UNI_FXY:我执行的情况,执行结果放到评论中了

    2018-04-26 14:33

  • xiaotutu6000 (作者)

    回复 DCloud_UNI_FXY:这个window.XMLHttpRequest 感觉返回的结果对象,感觉和 plus.net.xmlHTTPrequest 的返回的内容结构不一样。

    2018-04-26 14:44

追梦随想

追梦随想

用调试模式看看异步请求结果,保证服务器能正常访问,如果ajax请求成功,那就是后端问题,请求失败就看看访问速度问题,我没遇到你这种情况,新安装的也没问题

  • xiaotutu6000 (作者)

    找到问题根因了。是因为 ajax url请求,调用同一个接口,不能url一致,不然会有缓存了。导致第一次就会失败。后面就不会。但是怎么 程序不要去判断这个缓存,不知道怎么弄。

    2018-04-20 18:11

xiaotutu6000

xiaotutu6000 (作者)

找到问题根因了。是因为 ajax url请求,调用同一个接口,不能url一致,不然会有缓存了。导致第一次就会失败。后面就不会。但是怎么 程序不要去判断这个缓存,不知道怎么弄。

张一三

张一三

你应该用的是GET请求类型?POST应该不存在该问题

  • xiaotutu6000 (作者)

    不是哇。我用的是POST的请求。今天又出现这个问题。

    2018-04-21 16:58

  • xiaotutu6000 (作者)

    感觉超时设置的描述没起作用一样。直接报错,后台没有收到任何消息。但是我在浏览器上访问同一个地址。能够立马返回结果。

    2018-04-21 17:05

  • 张一三

    我有一台华为的手机现在会出现你类似的情况,但服务器是返回了数据的,只是mui.ajax没有将数据回调,而是直接报timeout超时错误,这种情况只出现在通过circle的下拉刷新时。但奇怪的是当下拉刷新出现超时错误后,我将下拉刷新动画关闭后,竟然数据又返回给了回调函数。也就是说我的这种情况,可能是circle模式下的下拉新刷新拦截了数据,但由于mui的某个bug造成了超时错误。

    2018-04-21 20:41

追梦随想

追梦随想

这还不简单,请求地址后面增加一个随机数或者当前的时间戳,图片验证码就是这样做的啊,难道你没做过网页验证码?

  • xiaotutu6000 (作者)

    我加了呀,昨天以为这样加了没有问题。结果发现,今天下午还是有这个问题。

    2018-04-21 20:52

  • 追梦随想

    回复 xiaotutu6000:那就不是缓存问题了

    2018-04-21 21:06

张一三

张一三

我有一台华为的手机现在会出现你类似的情况,但服务器是返回了数据的,只是mui.ajax没有将数据回调,而是直接报timeout超时错误,这种情况只出现在通过circle的下拉刷新时。但奇怪的是当下拉刷新出现超时错误后,我将下拉刷新动画关闭后,竟然数据又返回给了回调函数。也就是说我的这种情况,可能是circle模式下的下拉新刷新拦截了数据,但由于mui的某个bug造成了超时错误。

  • xiaotutu6000 (作者)

    我的不是不是出现在,下拉刷新这里。是在隔了一定时间,每次程序第一次启动的时候会出现。同时我去浏览器访问同一地址,后台是有响应的。感觉是应该是出在程序发送请求上,和浏览器有不同。但是不知道哪里不同。

    2018-04-21 20:56

  • xiaotutu6000 (作者)

    而且你说的这个情况,我碰到过一次。提示我超时后,我就去看代码了。我在回头看的时候,他自己就进去了。

    2018-04-21 20:57

  • xiaotutu6000 (作者)

    我看了我的第一条评论,那个家伙说,用 xmlHTTPRequest自己写一个请求来,能够解决这个问题。但是我自己模拟了半天,感觉依旧有这个问题。

    2018-04-21 20:58

  • 张一三

    我Android手机vivo暂时没有出现过你这情况,多试几部手机。也可能是HBuilder的问题,将HBuilder删除重新下载和将手机的真机基座也删除。再测试应用在线打包安装后会不会出现给问题。用了几年的HBuilder,遇bug无数,最后都一一解决了。除了平台本身的限制除外。

    2018-04-21 21:03

  • 张一三

    回复 xiaotutu6000:不要仅局限自己的手机,多测试几部手机,既然这个bug遇到的人少,也可能只在某些机型上出现。另外最重要的一点,HBuilder去下载最新Alpha版本,不要用旧的正式版,bug多多

    2018-04-21 21:07

  • 张一三

    回复 xiaotutu6000:当然也有可能Alpha版本又会遇到其他bug,但总体来说会更好点!

    2018-04-21 21:08

  • 张一三

    回复 xiaotutu6000:mui版本每次都应该更新到最新版

    2018-04-21 21:09

  • xiaotutu6000 (作者)

    回复 张一三:安卓、苹果机型都试过,同样的问题。你mui版本是多少?

    2018-04-21 21:20

  • xiaotutu6000 (作者)

    回复 张一三:不过我觉得应该是 mui的问题。我用jquery 带的ajax 也是同样的问题。

    2018-04-21 21:23

  • xiaotutu6000 (作者)

    回复 张一三:

    请求的url。看日志反应,是有链接上服务器,都进入到请求中。但是请求中,之后,就立马返回。服务器任何日志都没有产生。如果在出现这个问题的同时,去浏览器访问。是能够正常返回的。

    [LOG] : ----> http://www.hoyob.com/csck/sjbAutoLogin?ts=Sat Apr 21 2018 21:29:18 GMT+0800 (CST)


    [LOG] : ssssssssssssssssssssssssssssssssssssssssssssssss请求中


    [LOG] : ---- login.html ----> _shopLoginAutoLogin -> apply ## error ##:

    [LOG] : mui.ajax xhr error is {}

    [LOG] : mui.ajax type error is timeout

    [LOG] : mui.ajax errorThrown error is null

    [LOG] : ------>自动登陆重复标识 10

    [LOG] : ssssssssssssssssssssssssssssssssssssssssssssssss请求结束timeout |

    2018-04-21 21:40

  • 张一三

    回复 xiaotutu6000:在线打包一个最小测试工程,我在手机测试看会不会遇到你说的问题。貌似你用的是linux?我用的是Windows。HBuilder有linux版本么?

    2018-04-22 12:56

  • xiaotutu6000 (作者)

    我用的是windows 版本。我的后台是linux ,用的thinkphp

    2018-04-22 18:49

xiaotutu6000

xiaotutu6000 (作者)

官网的人,能帮忙过来解答下么?

  • 张一三

    建议这样的问题上传一个最小测试工程,让别人可以下载安装包在手机上测试下。没有最小测试工程,你问了也白问。

    2018-04-23 17:44

  • xiaotutu6000 (作者)

    好,那我上传一个最小工程。

    2018-04-24 16:08

xiaotutu6000

xiaotutu6000 (作者)

--重写了这个AJAX请求。经过1天1晚 的验证,基本验证无问题。记录一下,给后人留个经验吧。

/*  
 * ajax 请求参数  
 */  
function pubFun_ajax( interfaceName , data, timeout, html, funName, callback ){  
    console.log( '---- ' + html + ' ----> '+ funName +' -> 请求参数:' + JSON.stringify( data ) );  
    console.log( '----> http://'+ DKJALLHOST +'/csck/' + interfaceName + '?ts='+Date.parse(new Date()) );  

    //构建请求函数  
    var xhr = new plus.net.XMLHttpRequest();  

    xhr.open( 'POST', 'http://'+ DKJALLHOST +'/csck/' + interfaceName + '?ts='+Date.parse(new Date()) , true );  

    xhr.setRequestHeader('accept','application/json');  
    xhr.setRequestHeader('Content-Type','application/json');  
    xhr.setRequestHeader('accept-encoding' , 'gzip, deflate');  
    xhr.setRequestHeader('accept-language' , 'zh-CN,en-US;q=0.9');  
    xhr.setRequestHeader('origin' , 'file://');  
    xhr.setRequestHeader('x-requested-with' , 'XMLHttpRequest');  

    xhr.timeout = 10000;  
    xhr.responseType = "json";  

    xhr.onreadystatechange = function(){  
        switch ( xhr.readyState ) {  
            case 0 : { console.log( "xhr请求已初始化" ); break; }  
            case 1 : { console.log( "xhr请求已打开" ); break; }  
            case 2 : { console.log( "xhr请求已发送" ); break; }  
            case 3 : { console.log( "xhr请求已响应"); break; }  
            case 4 : {  
                if ( xhr.status == 200 ) {  
                    console.log( "xhr请求成功:"+xhr.responseText );  
                } else {  
                    console.log( xhr.status + "xhr请求失败:"+xhr.readyState );  
                }  
                break;  
            }  
            default :{  
                console.log('未知错误!'); break;  
            }  
        }  
    }  
    //成功处理事件  
    xhr.onload = function(e){   
        console.log( 'xhr请求成功事件处理' );  
        var str="lengthComputable="+e.lengthComputable+"loaded="+e.loaded+";total="+e.total;  
        console.log("onload: "+str);  

        console.log('后端返回数据返回数据 '+ this.responseText );  

        if(this.status == 200||this.status == 304){  

            if( callback ){  
                callback( JSON.parse( this.responseText ,true ) );  
            }  
            return ;  
        }  

    }  
    xhr.ontimeout = function( e ){  
        console.log('网络请求稍后超时,请稍后再试!');  
        if( callback ){  
            callback( {'code':'0000','content':''} );  
        }  
        return;  
    }  
    xhr.onerror = function( e ){  
        console.log('网络请求错误,请稍后再试!');  
        if( callback ){  
            callback( {'code':'0000','content':''} );  
        }  
        return;  
    }  
    xhr.send( JSON.stringify(data) );  

}
追梦随想

追梦随想

不用这么费事吧,jq不是有ajax请求吗,拿过来试试就行了,如果还是有你这问题,那就不是函数问题了,是你代码问题

  • xiaotutu6000 (作者)

    jquery 的有一样的 问题。我前后验证了几遍。

    我怀疑是,他们封装的Ajax 封装的机制问题。可能我对他们的底层还不熟悉吧。不然没办法解释,同样的接口。通过手机调用,后端接收不到任何数据,就失败。而同时在浏览器调用该接口,就能顺利返回。这点能证明两点

    1.后端应该无问题,

    2.中间的传播链路无问题。

    那问题最后最大的可能是,手机端的 HTTP 和请求,和浏览器的HTTP处理机制上不一样而导致的。既然他们的底层都是走 XMLHTTP协议,那只能从这个入手。AJAX封装的太高级了,个人能力有限不懂他们的全部玩法。

    2018-04-26 11:54

  • 追梦随想

    那就不清楚了,我这边用魅族、华为、苹果测试没这问题的,你的是什么机子,以后我也留意下

    2018-04-26 12:04

  • xiaotutu6000 (作者)

    嗯嗯。华为,苹果。两种机型都有。服务器在阿里云上买的经典网络,用的Thinkphp5.1 操作系统centos 6.5

    2018-04-26 12:23

  • xiaotutu6000 (作者)

    回复 追梦随想:不知道是不是 云服务器有关系,在网络层 阿里那边做了限制。

    2018-04-26 12:24

  • xiaotutu6000 (作者)

    回复 xiaotutu6000:我后发现后端的接收的包头,两者有细微区别。但具体是不是,我就无从验证了。

    2018-04-26 12:26

tank-88@qq.com

tank-88@qq.com

mui的Ajax是有很难复现的超时问题,感谢题主的解决方案

  • xiaotutu6000 (作者)

    嗯嗯,分享出来大家一起学习。

    2018-04-26 11:56

xiaotutu6000

xiaotutu6000 (作者)


修改后的代码执行情况

  • DCloud_UNI_FXY

    我看截图代码怎么是 xhr.response==200,不是应该 xhr.status 吗。当出问题的时候,打印下 xhr.status 和 xhr.responseText

    2018-04-26 19:54

  • xiaotutu6000 (作者)

    xhr.responseText 报错 The object is in an invalid state.

    2018-04-27 15:17

  • xiaotutu6000 (作者)

    回复 DCloud_UNI_FXY:打印情况,贴到评论里面去了

    2018-04-27 15:18

xiaotutu6000

xiaotutu6000 (作者)

执行结果

  • DCloud_UNI_FXY

    能否发一个测试代码文件,然后测试步骤,我这里测试一下

    2018-04-28 14:39

  • xiaotutu6000 (作者)

    回复 DCloud_UNI_FXY:哦知道了。我晚上打包一个附件给你

    2018-04-28 15:53

要回复问题请先登录注册