f***@163.com
f***@163.com
  • 发布:2020-04-16 20:57
  • 更新:2022-03-30 21:29
  • 阅读:2008

【报Bug】iOS在mui.plusReady中调用mui.ajax,有时候会出现跨域异常

分类:MUI

问题描述:

项目中的一个功能,打开一个画面,调用接口获取数据后在画面上显示,在mui.plusReady中使用mui.ajax调用此接口,有时候会直接进入到error回调,type为‘abort’,后台查看日志发现接口根本没有被调用。
调查此问题时通过HBuilderX输出日志得知,问题发生时,控制台输出日志【当前运行环境为WKWebview,需在plusReady事件触发后再调用mui.ajax,否则可能会执行失败或报Script error的错误】,由于我是在mui.plusReady中调用的mui.ajax,基本可以排除是我个人的原因造成的Bug

if(location.protocol === 'file:' && $.os.ios && window.webkit && window.webkit.messageHandlers && !(xhr instanceof plus.net.XMLHttpRequest)){  
    console.error("当前运行环境为WKWebview,需在plusReady事件触发后再调用mui.ajax,否则可能会执行失败或报Script error的错误")  
}

报错的代码片段,经排查报错原因为最后一个判断项目不满足,xhr的类型为:window.XMLHttpRequest

继续排查发现创建window.XMLHttpRequest的代码如下:

    $.ajaxSettings = {  
        type: 'GET',  
        beforeSend: $.noop,  
        success: $.noop,  
        error: $.noop,  
        complete: $.noop,  
        context: null,  
        xhr: function(protocol) {  
            return new window.XMLHttpRequest();  
        },  
        accepts: {  
            script: 'text/javascript, application/javascript, application/x-javascript',  
            json: jsonType,  
            xml: 'application/xml, text/xml',  
            html: htmlType,  
            text: 'text/plain'  
        },  
        timeout: 0,  
        processData: true,  
        cache: true  
    };

其中xhr()方法返回一个XMLHttpRequest对象,方法调用位置为:

var xhr = settings.xhr(settings);

而此方法在

    $.plusReady(function() {  
        $.ajaxSettings = $.extend($.ajaxSettings, {  
            xhr: function(settings) {  
                if (settings.crossDomain) { //强制使用plus跨域  
                    return new plus.net.XMLHttpRequest();  
                }  
                //仅在webview的url为远程文件,且ajax请求的资源不同源下使用plus.net.XMLHttpRequest  
                if (originAnchor.protocol !== 'file:') {  
                    var urlAnchor = document.createElement('a');  
                    urlAnchor.href = settings.url;  
                    urlAnchor.href = urlAnchor.href;  
                    settings.crossDomain = (originAnchor.protocol + '//' + originAnchor.host) !== (urlAnchor.protocol + '//' + urlAnchor.host);  
                    if (settings.crossDomain) {  
                        return new plus.net.XMLHttpRequest();  
                    }  
                }  
                if ($.os.ios && window.webkit && window.webkit.messageHandlers) { //wkwebview下同样使用5+ xhr  
                    return new plus.net.XMLHttpRequest();  
                }  
                return new window.XMLHttpRequest();  
            }  
        });  
    });

被覆盖,正常情况下,$.plusReady会先调用,mui.ajax运行时调用settings.xhr时调用的是覆盖后的方法,正确使用可以跨域的plus.net.XMLHttpRequest;而错误发生时,先调用了mui.ajax,后调用了$.plusReady,导致使用的是无法跨域的window.XMLHttpRequest,所以数据无法发送至服务端

若将mui.js中的所有new window.XMLHttpRequest()改为new plus.net.XMLHttpRequest();,此问题将不会重现

或者在mui.ajax之前,调用

mui.ajaxSettings = mui.extend(mui.ajaxSettings, {  
        xhr: function(settings) {  
            return new plus.net.XMLHttpRequest();  
        }  
});

强制xhr方法返回plus.net.XMLHttpRequest实例

希望DCloud能及时查明原因并修正

App运行环境说明

[iOS版本号]
13.3.1

[手机型号]
iPhone XR MRYX2LL/A

联系方式

[QQ] 2060729983

2020-04-16 20:57 负责人:无 分享
已邀请:
常山赵子龙

常山赵子龙 - 慎始如终,则无败事!

同样不行 请问解决了吗?

3***@qq.com

3***@qq.com

整个项目全变成跨域的问题了 除了安卓端 全挂

小叮叮

小叮叮 -

这个问题我也遇到了,有人解决掉了吗?是怎么解决的

该问题目前已经被锁定, 无法添加新回复