持續(xù)更新...
前言
在日常開發(fā)過程中,現(xiàn)在已經(jīng)是第二次碰見華為手機(jī)在 APP 內(nèi)置 WebView 上瀏覽圖片出現(xiàn)圖片不顯示的問題了干像,在 wap 端是不存在這個(gè)問題的侄旬。還記得第一次碰見這個(gè)問題的時(shí)候是在與移動(dòng)端開發(fā)人員探討圖片不顯示 bug搏讶,排除了樣式鸽捻、圖片因素和 js 干擾后,最后將矛頭指向 WebView 加載問題喉誊,然后移動(dòng)端開發(fā)人員在查閱 WebView 文檔后指出是 WebView 模式引起的渔隶。作為一名專業(yè)的螺絲釘制造者羔挡,有必要將問題總結(jié)下來,讓大家少踩坑~
WebView 的模式
- Android@version < v5.0,默認(rèn)是采用的 MIXED_CONTENT_ALWAYS_ALLOW 模式婉弹,即總是允許 WebView 同時(shí)加載 Https 和 Http睬魂;
- Android@version >= v5.0,默認(rèn)用 MIXED_CONTENT_NEVER_ALLOW 模式镀赌,即總是不允許 WebView 同時(shí)加載 Https 和 Http氯哮。
安全問題一直都是值得開發(fā)者探討的問題,開發(fā)者本應(yīng)對每個(gè)微小細(xì)節(jié)把關(guān)商佛,保護(hù)好每一份數(shù)據(jù)喉钢。從 Android 5.0 開始,WebView 默認(rèn)是采用的 MIXED_CONTENT_NEVER_ALLOW 模式良姆,不再支持同時(shí)加載 Https 和 Http 混合模式肠虽。這主要處于對網(wǎng)絡(luò)數(shù)據(jù)安全性的考慮,官方默認(rèn)推薦使用 https玛追。對于需要修改模型的税课,可以自行修改配置,不過實(shí)測在一些機(jī)型如華為 P30痊剖,WebView 使用混合 http 和 https 也不是萬全之策韩玩,況且在規(guī)范上應(yīng)盡量保持只用 http 或只用 https 為妙。
MIXED_CONTENT_NEVER_ALLOW
此模式要求 WebView 使用 https 加載資源陆馁。WebView 不允許
一個(gè)安全的站點(diǎn)(https)去加載非安全
的站點(diǎn)內(nèi)容(http),比如找颓,https 網(wǎng)頁內(nèi)容的圖片是 http 鏈接。強(qiáng)烈建議 App 使用這種模式叮贩,因?yàn)檫@樣更安全
击狮。
MIXED_CONTENT_ALWAYS_ALLOW
允許 https 環(huán)境加載 http 資源,不安全益老。此模式下 WebView 是可以在一個(gè)安全的站點(diǎn)(Https)里加載非安全的站點(diǎn)內(nèi)容(Http),這是 WebView 最不安全
的操作模式彪蓬,盡可能地不要使用
這種模式。
MIXED_CONTENT_COMPATIBILITY_MODE
允許 https 環(huán)境兼容式阻塞加載 http 資源捺萌,較安全寞焙。此模式下,當(dāng)涉及到混合式內(nèi)容時(shí)互婿,WebView 會(huì)嘗試去兼容
最新 Web 瀏覽器的風(fēng)格。一些不安全的內(nèi)容(Http)能被加載到一個(gè)安全的站點(diǎn)上(Https)辽狈,而其他類型的內(nèi)容將會(huì)被阻塞
慈参。這些內(nèi)容的類型是被允許加載還是被阻塞可能會(huì)隨著版本的不同而改變,并沒有明確的定義刮萌。這種模式主要用于在 App 里面不能控制內(nèi)容的渲染驮配,但是又希望在一個(gè)安全的環(huán)境下運(yùn)行。
實(shí)戰(zhàn)情景
華為 P30 App 內(nèi)置 WebView 環(huán)境加載圖片不顯示
- 測試環(huán)境
- 運(yùn)行終端:app 內(nèi)置 WebView 環(huán)境
- 手機(jī)型號:華為 P30
- os:Android 9.0
對于這個(gè)圖片加載不顯示的問題做了幾個(gè)嘗試:
- 在不修改原本加載資源的情況下,使用混合模式
MIXED_CONTENT_COMPATIBILITY_MODE
嘗試加載資源
/*app啟用WebView混合模式嘗試解決圖片不顯示*/
webSetting.setBlockNetworkImage(false); // 不阻塞網(wǎng)絡(luò)圖片
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//允許混合(http壮锻,https)
//webSetting.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
webSetting.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
}
在設(shè)置好混合模式后來了一波測試琐旁,本以為順利搞掂,最后殺出一個(gè)程咬金說有些圖片不夠s
猜绣,所以不見得能顯示出來(灰殴;д;)掰邢。
啊不牺陶,是因?yàn)橛行﹫D片沒有安全證書問題顯示不出來。ヾ(o?ω?)?
驀然回首辣之,發(fā)現(xiàn)在這個(gè) https 安全環(huán)境的問題還是挺多的呀掰伸,有些機(jī)型加載 http 資源沒有安全證還是不讓顯示的。有安全證書保平安吶怀估!混合模式并不是萬能的狮鸭!
回到問題,當(dāng) WebView 加載網(wǎng)頁發(fā)生證書認(rèn)證錯(cuò)誤時(shí)多搀,會(huì)調(diào)用 WebViewClient 類的 onReceivedSslError 方法歧蕉,在這個(gè)方法里,可以點(diǎn)擊源碼看到 SslErrorHandler 中有兩個(gè)主要的方法可以調(diào)用:
- cancel():停止加載問題頁面
- proceed():忽略 SSL 證書錯(cuò)誤酗昼,繼續(xù)加載頁面
如果不考慮證書安全廊谓,則可以這樣忽略報(bào)錯(cuò):
WebView.setWebViewClient(new WebViewClient() {
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
handler.proceed();//接受所有網(wǎng)站的證書
}
});
然后對于不顯示的圖片,只能讓后臺手動(dòng)修改鏈接麻削,改為對應(yīng)的 https 什么的蒸痹。
另外,在測試時(shí)發(fā)現(xiàn) X5 內(nèi)核的 WebView 中呛哟,是找不到 MIXED_CONTENT_ALWAYS_ALLOW 這些模式參數(shù)的叠荠,對此要手動(dòng)判斷是否 X5 并設(shè)值:
MIXED_CONTENT_NEVER_ALLOW = 0;
MIXED_CONTENT_ALWAYS_ALLOW = 1;
MIXED_CONTENT_COMPATIBILITY_MODE = 2;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// 混合模式
webSetting.setMixedContentMode(2);
}
測試至此,本人對混合模式是持謹(jǐn)慎態(tài)度的扫责,不太建議使用榛鼎,除非迫不得已的情況吧。
從規(guī)范上來講鳖孤,要么全部使用 http 的資源者娱,要么全部使用 https。
- 最后推薦全部資源使用 https
- 對于愛偷懶的我來講(~ ̄ ▽  ̄)~ 苏揣,更喜歡這種格式書寫:
//www.xxx.com/