问题描述:
项目中的一个功能,打开一个画面,调用接口获取数据后在画面上显示,在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
3 个回复
常山赵子龙 - 慎始如终,则无败事!
同样不行 请问解决了吗?
3***@qq.com
整个项目全变成跨域的问题了 除了安卓端 全挂
小叮叮 - 张
这个问题我也遇到了,有人解决掉了吗?是怎么解决的