mobile
mobile copied to clipboard
用zepto1.1.6发ajax在特定安卓机出现INVALID_STATE_ERR: DOM Exception 11异常
问题描述:
在用小米2,安卓版本4.01.07,qq5.9.1,zepto1.1.6测试页面的时候发现页面报JS错误。
原因:
具体跟进发现zepto1.1.6里有这么一段
if (settings.headers) for (name in settings.headers) setHeader(name, settings.headers[name])
xhr.setRequestHeader = setHeader
var async = 'async' in settings ? settings.async : true
xhr.open(settings.type, settings.url, async, settings.username, settings.password)
第一行语句会给xhr.withCredentials赋值。 在特定机型特定系统特定浏览器下,
- 给xhr.withCredentials赋值
- 调用xhr.open方法 如果2在1之后调用会导致异常。
看看w3c里的描述: http://www.w3.org/TR/2012/WD-XMLHttpRequest-20120117/#the-withcredentials-attribute 里面有这么一段:
- If the state is not UNSENT or OPENED, throw an "InvalidStateError" exception and terminate these steps.
- If the send() flag is set, throw an "InvalidStateError" exception and terminate these steps. 意味着规范里写着只要在send之前调用,open和withCredentials的顺序应该不会导致InvalidStateError才对。所以zepto这样写应该还是符合规范的,作者之所以不把open提前,原因可见https://github.com/madrobby/zepto/issues/921。
解决方案:
快速的解决方案可以考虑:
- https://github.com/madrobby/zepto/issues/921 这里提到的open提前。
- try catch捕获异常
- https://github.com/mscienski/zepto/commit/d4ddb345c3b76315867aeebbc0afbfab53eb9c03 这里提到的对ajax.js的修复。
赞。
good,支持疑难杂症的分享~
提供一个经过验证的解决方案,不用修改Zepto.ajax的:
$.ajax({
type: type,
url: url,
beforeSend: function(xhr) {
try {
xhr.withCredentials = true;
} catch (e) {
var nativeOpen = xhr.open;
xhr.open = function() {
var result = nativeOpen.apply(xhr, arguments);
xhr.withCredentials = true;
return result;
};
}
},
data: data,
cache: false,
timeout: 5000,
success: function(data) {
func(data)
},
error: function() {
alert('error')
}
});