最近在作一个手机上架设微服务然后用 webview 交互的需求。 在手机异常时,pc 端始终 ok。代码一样的 Android webview download listener 被触发时 有可能会收到 blob:http://..开头的 url 然而无法读取。 最终找到了一种解决方案:用 js 转化 bloburl 为 base64 。
"javascript:" + "var xhr = new XMLHttpRequest();" + //js 交互类 WebUtils "var util = window.WebUtils;" + "xhr.open('GET', '" + blobUrl + "', true);" + "xhr.setRequestHeader('Content-type','application/sb3');" + "xhr.responseType = 'blob';" + "xhr.onload = function(e) {" + " if (this.status == 200) {" + " var blobPdf = this.response;" + " var reader = new FileReader();" + " reader.readAsDataURL(blobPdf);" + " reader.onloadend = function() {" + " base64data = reader.result;" + "console.log(base64data);" + //已经拿到了 base64 字节码 io 转 file 下边是我自己的方法 " util.getBase64(base64data);" + " }" + " }else{alert(this.status);" + "}" + "};" + "xhr.onerror=function(data){alert(data);};" + "xhr.send();"
然而遇到了另一个 bug。xhr.onerror() 始终提示 [object ProgressEvent]. 卡在这 3 天 搜遍全网 抱了几个大腿,顺便学习了 blob 的知识 发现 服务器代码里有 回收 bloburl 的操作 oh~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 注释了这两行代码,完美 // window.URL.revokeObjectURL(url); // document.body.removeChild(downloadLink); 在下载后 别忘了 js 运行下这两行代码 回收哦
基础的 webview 配置 别忘了 webSettings.setAppCacheEnabled(true) webSettings.databaseEnabled = true webSettings.domStorageEnabled = true webSettings.setAppCachePath(this.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).absolutePath) webSettings.useWideViewPort = true webSettings.loadWithOverviewMode = true webSettings.pluginState = WebSettings.PluginState.ON if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { webSettings.setAllowFileAccessFromFileURLs(true); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { webSettings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW }
希望遇到同样问题的 Android 小伙伴看倒这个文章,这是 h5 的坑