升級 HTTPS 后 Android WebView 無法加載圖片
問題
前端組例行發布網頁數小時候后,突然間 Android 打不開網頁中的圖片了。IOS 也有一些其他問題。然而通過微信和瀏覽器打開網頁是完全正常的。
分析
通過 Charles 抓包,發現 Android WebView 在加載網頁時,請求了網頁的文本數據,但并未請求圖片。分析網頁文本數據,看到網頁中的 圖片地址是 HTTP 的,以為 WebView 應該可以正常加載 HTTP 資源的,并未深究。
估計 bug 和升級 HTTPS 有關,于是先重寫了 WebViewClient.onReceivedSslError 方法試試,然而并無效果。
繼續研究看是否有其他線索,看到 chromium 輸出的 log 后意識到網頁是 HTTPS 時,其請求的資源數據也應該是 HTTPS。
chromium log 如下
I/chromium: [INFO:CONSOLE(0)] "Mixed Content: The page at 'https://*' was loaded over HTTPS, but requested an insecure image 'http://****3a.jpg_1483706839'. This request has been blocked; the content must be served over HTTPS.", source: https://*.***.com/#!/?ids=** (0)
解決
有了 log 和確定問題所在就好改了。代碼如下
webView.setWebViewClient(new WebViewClient(){
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error){
handler.proceed();
}
});
Android webview 從 Lollipop 開始默認不允許MixedCotentMode,還需要做以下修改
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { webview.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
后臺整體更換圖片資源 HTTP 鏈接為 HTTPS 后 ,老版本 APP 打開網頁也可以顯示圖片了。
總結
- WebView加載網頁 出問題時分析網頁源碼和抓包比較麻煩,可以通過看 chromium log來直觀的分析問題。
- 第一天上線 HTTPS,第二天傍晚才出現問題,期間有二十多小時,有點奇怪 CDN 緩存時間有那么長么。
2017年01月08日更
只用開啟 MixedCotentMode
就可以滿足需求了,不需要 handler.proceed()
。
直接 handler.proceed()
太粗暴,Google Play 會警告。