Android WebView中终止XMLHttpRequest避免net:ERR_INSUFFICIENT_RESOURCES异常
解决Android API 25 WebView中终止XHR下载触发ERR_INSUFFICIENT_RESOURCES的问题
我之前在维护API 25版本的Android应用时,正好碰到过完全一样的问题——用XHR下载测速文件,调用abort()后总会抛出net:ERR_INSUFFICIENT_RESOURCES异常。这个问题主要源于API 25对应的WebView内核(Chromium 53)在处理XHR终止时的资源释放逻辑存在缺陷。下面是几个经过实际验证的解决方案,按推荐程度排序:
1. 改用Fetch API + AbortController替代XMLHttpRequest
Fetch API的终止机制设计得更规范,API 25及以上的WebView已经支持这个组合,而且不会触发资源不足的异常。示例代码如下:
// 创建AbortController实例 const controller = new AbortController(); const signal = controller.signal; // 发起下载请求 fetch('你的测速文件URL', { signal }) .then(response => { // 处理下载逻辑(比如读取流) const reader = response.body.getReader(); return reader.read(); }) .catch(error => { if (error.name === 'AbortError') { // 正常终止,无需处理异常 console.log('下载已主动终止'); } else { // 处理其他真实错误 console.error('下载出错:', error); } }); // 10秒后终止下载 setTimeout(() => { controller.abort(); }, 10000);
这个方案是最推荐的,不仅解决了异常问题,代码也更符合现代前端规范。
2. 优化XMLHttpRequest的终止流程(兼容旧代码)
如果不想替换XHR,可以尝试在调用abort()前先做一些资源清理,减少WebView内核的资源冲突:
let xhr = new XMLHttpRequest(); xhr.open('GET', '你的测速文件URL'); xhr.responseType = 'blob'; xhr.onprogress = function(e) { // 处理测速进度逻辑 }; xhr.onerror = function(e) { // 这里判断是否是主动终止导致的错误 if (xhr.readyState === XMLHttpRequest.UNSENT || xhr.readyState === XMLHttpRequest.DONE) { // 主动终止的情况,忽略异常 return; } // 处理真实错误 }; xhr.send(); // 10秒后终止下载 setTimeout(() => { // 先移除所有事件监听 xhr.onprogress = null; xhr.onerror = null; xhr.onload = null; // 再调用abort xhr.abort(); // 最后释放引用 xhr = null; }, 10000);
这个方法通过提前清理监听和释放引用,降低了内核资源泄漏的概率,能在大部分场景下避免异常。
3. 拦截WebView的错误回调(临时治标方案)
如果上面的方法都无法生效,可以在Android端自定义WebViewClient,拦截这个特定错误,不让它传递到业务逻辑中:
webView.setWebViewClient(new WebViewClient() { @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { super.onReceivedError(view, request, error); // 判断是否是目标异常 if (error.getErrorCode() == WebViewClient.ERROR_INSUFFICIENT_RESOURCES) { // 检查请求是否是测速下载的URL,避免误拦截其他错误 if (request.getUrl().toString().contains("你的测速文件标识")) { // 忽略这个异常,不做错误处理 return; } } // 处理其他正常错误 handleError(error); } });
这个方案只是屏蔽了错误提示,并没有从根本上解决资源问题,但可以作为紧急情况下的临时方案。
额外提示
- API 25的WebView内核较老,这个问题在Android 8.0(API 26)及以上的WebView中已经被修复,如果应用可以升级最低版本,建议直接升级到API 26+。
- 测速场景下,也可以考虑在服务器端设置一个“可中断下载”的接口,客户端发送终止请求后,服务器主动关闭连接,这样XHR会自然触发
onloadend而不是异常。
内容的提问来源于stack exchange,提问作者Shai
相关产品推荐
相关产品推荐

