微信iOS客戶端將於2017年3月1日前逐步升級為WKWebview內核,需要網頁開發者提前做好網站的兼容檢查和適配。
背景
WKWebView 是蘋果在iOS 8中引入的新組件,目的是提供一個現代的支持最新Webkit功能的網頁瀏覽控件,擺脫過去 UIWebView的老、舊、笨,特別是內存占用量巨大的問題。它使用與Safari中一樣的Nitro JavaScript引擎,大大提高了頁面js執行速度。
切換方法
iOS微信6.5.3版本開始支持開發者手動切換WKWebview和UIWebview,使開發者可提前對WKWebview進行適配。
手動切換入口:
在微信會話列表頁點擊右上角“加號按鈕”,選擇菜單中的”添加朋友”,在添加朋友界面的搜索框中輸入字符串:“:switchweb”,再點擊鍵盤右下角搜索按鈕。切換成功后會提示當前使用的內核是UIWebview或是WKWebview。
校驗切換方法:
通過命令成功切換到WKWebview后,可通過以下方法驗證當前網頁使用的是否是WKWebview內核。
微信內任意入口進入任意網頁,在網頁加載成功后向下拉動頁面(或點擊網頁右上角菜單按鈕),使之顯示出地址欄,當地址欄以 “此網頁由” 開頭即為當前使用WKWebview,若以“網頁由”則是使用的UIWebview。
頁面如何判斷當前使用的webview內核:
在頁面中可通過微信注入的window.__wxjs_is_wkwebview變量判斷當前使用的webview內核。 iOS微信6.5.3及其之后的版本 window.__wxjs_is_wkwebview 為true時是使用WKWebview,為 false或者 “undefine”時是 UIWebview 。
前端適配關注的要點
適配的首要原則:若不能區分是WKWebview的新特性新行為還是微信內部邏輯導致原有頁面出現問題時,可使用測試頁面分別在Safari和微信中的WKWebview內核分別測試,用以快速定位問題產生的原因。
適配指南
切換為WKWebview后,微信中的Webview行為和Safari中保持高度一致,唯一的區別是微信Webview中會注入微信JSBridge相關的腳本。所以適配的重點需要關注以下幾個方面:
一:頁面功能是否正常
二:頁面屏幕適配是否正常 三:頁面行為是否正常(例如用戶在瀏覽頁面時點擊返回按鈕返回上一個頁面時的頁面邏輯是否正常)
四:頁面使用的語法是否兼容。
五:JSSAPI是否正常完美的工作。
六:重點關注Cookie和LocalStorage等相關的邏輯是否正常。
七:若服務器有設置返回 Cache-Control緩存有效時間,則需要檢查相關邏輯是否正常。
正常情況下,你的頁面是不需要做特別的適配,但若你的頁面有涉及到以下幾個受影響的邏輯,則需要根據適配建議進行適配和確認。
JSAPI相關適配
一:將不再支持cache
變化:在WKWebview中將暫不支持cache jsapi。
適配建議:所有使用此api的開發者可去掉頁面相關邏輯。
二:頁面通過LocalID預覽圖片
變化:不再支持通過使用chooseImage api返回的localld以如:”img src=wxLocalResource://50114659201332”的方式預覽圖片。
適配建議:
1. 在iOS微信6.5.3版本及之后的版本中,使用新增的jsapi:getLocalImgData 拿到LocalID對應的圖片base64編碼后再在前端頁面中顯示。
2. 如果引入了頁面有引入JSSDK,則直接將JSSDK升級為1.2.0最新版本即可幫助頁面自動適配。(目前JSSDk線上版本是 1.0.0 和 1.1.0,更新版本為1.2.0 ,https://res.wx.qq.com/open/js/jweixin-1.2.0.js )
三:有使用JSSDK,並且使用了wx.config進行權限授權需關注jsapi調用的失敗問題
變化:WKWebview的內部實現變更使我們對微信內的頁面jsapi權限管理做了一定邏輯上的調整,有極小可能會發生以前授權正常的jsapi獲取權限不正常,從而導致調用jsapi失敗。
適配建議:
1. iOS微信6.5.1,WKWebview在此版本中已知有以下問題:頁面使用HTML5的History API pushState; popstate; replaceState等控制頁面導航(典型的如單應用頁面),同時使用JSSDK的wx.config為jsapi授權,此時大幾率會出現jsapi因為無權限而調用失敗的問題。 在6.5.1中頁面若可能的情況下,可使用Anchor hash技術替換History技術來解決此問題。
2. iOS微信6.5.2及其之后版本,將不會存在以上問題,但不能100%確認有使用到 history或hash技術更改頁面導航地址的頁面完全沒有此類問題,依然需要開發者注意關注此類問題。
Cookie和LocalStorage設置相關
一:退出微信賬號后,將會清空所有Cookie和LocalStorage。
二:頁面功能依賴Cookie,或有涉及到Cookie的相關邏輯
變化:WKWebview內部實現變更,會影響目前頁面Cookie相關的邏輯,例如跨域存取Cookie和頁面的資源或圖片存儲服務器依賴校驗Cookie來返回數據等情況。
問題說明:在訪問一個頁面A時,如果頁面A引用了另一個頁面B的資源(頁面A和B為不同的域名),這時頁面B就認為是第三方頁面。若在頁面B中設置Cookie,就會命中WKWebview下阻止第三方跨域設置Cookie的安全策略,導致問題出現。
適配建議:
在WKWebview中是默認阻止跨域的第三方設置Cookie。所有通過Cookie傳遞的信息,可通過業務后台存儲需要傳遞的信息,然后給頁面一個存儲信息相對應的access_token加密碼,然后通過Url中加入自己業務的access_token進行頁面間信息傳遞。
如果頁面的資源或圖片存儲的服務器依賴校驗Cookie來返回數據的情況,在切換到WKWebview后,在微信內長按保存,或者點擊預覽大圖時,將不會完整的帶上所設置的Cookie,會導致圖片保存失敗或預覽失敗。除了此種情況,開發者不用擔心其他情況下Cookie丟失的問題,所有請求都會帶上完整的Cookie。
頁面視頻小窗播放
變化:iOS微信6.5.3及其之后的版本中,Webview默認支持小窗播放。
開發者需要特別注意小窗播放需要前端同時適配iOS10和iOS10以下的低版本
適配建議:需要完全按照以下代碼設置video標簽才可同時兼容不同的iOS版本
<video webkit-playsinline playsinline> </video>
WKWebview頁面行為與Safari完全一致,會導致頁面依賴UIWebview頁面行為的邏輯失效或異常:(可根據業務自身邏輯,實現測試頁面后分別在Safari和微信WKWebview中驗證)
一:Safari或微信WKWebview中 頁面A跳轉到頁面B再返回頁面A后不會重新執行Script和Ajax(也不會觸發頁面reload)。
二:Safari或微信WKWebview中,在頁面彈出輸入鍵盤后,會觸發jQuery的resize事件,而在UIWebView下不會。
三:Safari或微信WKWebview中, window unload 事件在只有刷新才能觸發,退出頁面或者跳轉到其他頁面都無法觸發。
四:Safari或微信WKWebview中,極少數情況下某些特殊實現的頁面點擊事件會失效。
其他問題
一:頁面自定義重載標准方法或者函數時,需要確保不會與微信注入Webview中的JSBridge相關方法沖突,否則會導致頁面在微信中的行為異常。
二:強烈建議不要在無法確保頁面緩存策略和邏輯與服務器邏輯完全保持一致的情況下冒然設置html頁面文件(除了html類型的頁面,頁面引用的其他資源或腳本按照自身業務合理設置即可)相關的Cache-Control屬性。
典型案例:
如果第一次訪問頁面A.html 服務器302跳轉到A1.html?uid=111設置Cache-Control: max-age=60,此A1.html的uid參數是服務器設置的111(此時A1.html已經被客戶端緩存)。 第二次訪問頁面A.html ,服務器同樣302跳轉到A1.html?uid=222,但是此時的A1.html頁面的uid參數是222, 客戶端帶參數完整鏈接詢問服務器緩存是否可用, 服務器返回緩存可用304,但是客戶端緩存的A1.html完整鏈接帶的uid參數是111,所以本地找不到數據,此時加載頁面就會失敗。