1. 程式人生 > >WebView載入html圖片不顯示問題

WebView載入html圖片不顯示問題

參考連結

近期在專案中出現了一個問題,WebView載入html時,部分圖片顯示不出來,一直顯示裂圖,多方搜尋,可能是因為http和https的混合問題。

原因

在Android5.0 以及以上的系統,當WebView載入的連結為Https開頭,但是連結裡面的內容,比如圖片為Http連結,這時候,圖片就會載入不出來。

這個是http和https的混合問題。而且只會在Android5.0及以上的出現。那是因為從Android5.0開始,WebView預設不支援同時載入Https和Http混合模式。

分析

從Android5.0以後,當一個安全的站點(https)去載入一個非安全的站點(http)時,需要配置Webview載入內容的混合模式,一共有如下三種模式:

  • MIXED_CONTENT_NEVER_ALLOW:Webview不允許一個安全的站點(https)去載入非安全的站點內容(http),比如,https網頁內容的圖片是http連結。強烈建議App使用這種模式,因為這樣更安全。
  • MIXED_CONTENT_ALWAYS_ALLOW:在這種模式下,WebView是可以在一個安全的站點(Https)里加載非安全的站點內容(Http),這是WebView最不安全的操作模式,儘可能地不要使用這種模式。
  • MIXED_CONTENT_COMPATIBILITY_MODE:在這種模式下,當涉及到混合式內容時,WebView會嘗試去相容最新Web瀏覽器的風格。一些不安全的內容(Http)能被載入到一個安全的站點上(Https),而其他型別的內容將會被阻塞。這些內容的型別是被允許載入還是被阻塞可能會隨著版本的不同而改變,並沒有明確的定義。這種模式主要用於在App裡面不能控制內容的渲染,但是又希望在一個安全的環境下執行。

在Android5.0以下,預設是採用的MIXED_CONTENT_ALWAYS_ALLOW模式,即總是允許WebView同時載入Https和Http;而從Android5.0開始,預設用MIXED_CONTENT_NEVER_ALLOW模式,即總是不允許WebView同時載入Https和Http。

解決方案

在webview載入頁面之前,設定載入模式為:
MIXED_CONTENT_ALWAYS_ALLOW(不太安全),
或者
MIXED_CONTENT_COMPATIBILITY_MODE(個人建議)。

另外在webview設定中還可以加上另外一個設定:

websettings.setBlockNetworkImage
(false);

加上混合內容模式設定,程式碼如下:

/*解決圖片不顯示*/
websettings.setBlockNetworkImage(false);//不阻塞網路圖片
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    //允許混合(http,https)
	//websettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
    websettings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
}

通過上面的設定,發現有些圖片仍然不能顯示。又經過多方搜尋,發現了其他問題。

圖片不顯示原因還有可能是證書問題

只要涉及到https,大家都會第一時間想到證書驗證。當然,這是沒問題的。如果有要求,這個證書驗證是必須的。一般情況下,都是需要證書的(有證書畢竟安全些)。

Android WebView元件載入網頁發生證書認證錯誤時,會呼叫WebViewClient類的onReceivedSslError方法,在這個方法裡,我們可以點選原始碼看到SslErrorHandler中有兩個主要的方法可以呼叫

  • 【1】cancel( ):停止載入問題頁面
  • 【2】proceed( ):忽略SSL證書錯誤,繼續載入頁面

如果我們不考慮證書安全,則可以直接這樣寫

webView.setWebViewClient(new WebViewClient() {
    @Override
    public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
        handler.proceed();//接受所有網站的證書
    }
});