前言
原來小程序裡的webView又這麼多注意點。今日早讀文章由騰訊imweb@結一投稿分享。
正文從這開始~~
對於開發者來說,如果 H5 頁面能夠直接嵌入到小程序那是再好不過了,而 web-view 組件正好就提供了這麼個功能(個人類型與海外類型的小程序暫不支持使用)。簡單來說它是一個可以用來承載網頁的容器,會自動鋪滿整個小程序頁面。 雖然這帶來了很大的便利,但是也還是有很多需要注意的地方。
賬號權限
如果要在小程序中使用 web-view 組件,則首先需要開發者賬號不僅是該小程序的開發者而且還有網頁開發權限,這需要在該小程序關聯的公眾號裡面綁定開發者賬號為開發者。不然在開發工具裡面會彈窗提示沒有網頁開發權限。提示如下:
業務域名
如果 web-view 組件的 src 屬性指向的不是關聯的公眾號文章,而是其他網頁,則需要登錄小程序管理後臺(設置 -> 開發設置)中配置業務域名,如下圖:
配置業務域名的時候會提示需要上傳驗證文件到該域名下進行驗證。如果該域名下沒有驗證文件或驗證文件錯誤,則 web-view 頁面直接提示報錯,無法正常訪問。
除此之外,如果頁面中有其他鏈接跳轉到非業務域名,進行跳轉的時候也會報錯導致無法正常訪問,如富文本內容中的鏈接,iframe,數據上報或支付跳轉等其他非業務域名。
另外:避免在鏈接中帶有中文字符,在 iOS 中會有打開白屏的問題,建議加一下 encodeURIComponent
登錄態
小程序登錄態與 web-view 頁面登錄態屬於兩套隔離的系統。所以得想辦法讓小程序中的登錄態傳入到 web-view 頁面中。目前最簡單也是最常用的方案是把 cookie作為 url 參數傳入,然後再在 H5 中獲取並設置 cookie,為了提高點難度,也可以搞點小動作。
當然更高明的辦法是搭建一箇中間服務,傳入要跳轉的 url 和 code,中間服務通過 code 得到 session,再返回 302 重定向地址。
組件層級
web-view 組件屬於原生組件,所以層級很高,如果需要覆蓋則需要使用 cover-view 組件。但是 cover-view 組件在開發工具上是看不到覆蓋效果的,安卓默認也不能覆蓋,只有 IOS 默認會覆蓋。所以為了得到想要的效果,得使用一些非常手段:
對於安卓的默認不能覆蓋,目前的解決方案是執行 setTimeout 延遲實現 cover-view 的顯示,讓 web-view 先顯示,cover-view 後顯示。
對於開發工具看不到,如要調試效果則可以先註釋掉 web-view 組件
除此之外,封裝一個組件的時候,如果需要蓋住 web-view,肯定得選擇 cover-view 組件。但是如果這個組件不僅應用在 web-view 頁面,還應用在普通的小程序頁面。 cover-view 又會引來另一個問題:彈窗浮層根本蓋不住。如一些右下角的諮詢按鈕,既應用在小程序頁面中,也應用在 web-view 頁面中。所以做組件的時候可以做一個屬性判斷,如果是 web-view 頁面則使用 cover-view,否則使用 view。
另外 cover-view 組件中的 button 組件並不是真的,而是用 cover-view 模擬出來的。所以修改樣式的話,需要注意點。
web-view 頁面中小程序環境判斷
官網有記載在網頁內可通過 window.__wxjs_environment 變量判斷是否在小程序環境,並且建議在 WeixinJSBridgeReady 回調中使用,也可以使用 JSSDK (1.3.2 以上版本) 提供的 getEnv 接口。代碼如下:
// web-view下的頁面內
function ready() {
console.log(window.__wxjs_environment === 'miniprogram') // true
}
if (!window.WeixinJSBridge || !WeixinJSBridge.invoke) {
document.addEventListener('WeixinJSBridgeReady', ready, false)
} else {
ready()
}
// 或者
wx.miniProgram.getEnv(function(res) {
console.log(res.miniprogram) // true
})
實際情況,一般都會直接用 window.__wxjs_environment。但是如果頁面沒有加載完,它是不準的,而且如果是 web-view 中進入到第二個頁面,安卓也拿不到該值,總之就一個字”很不靠譜”。
既然“不靠譜”,那就有了通過 URL 裡面加參數來判斷,這是鐵定的穩。如添加一個 mp 參數(https://m.ke.qq.com/course/xxx?mp=1)。但是如果頁面有幾個跳轉,總不能每個都去判斷下加上 mp 參數吧。所以建議在進入的第一個頁面直接種下 storage,往後的根據 storage 來判斷就好了。
通過這三層保證(變量 || mp 參數 || storage),只要一個為真,則為小程序環境。這樣鎖定小程序環境很穩。
另外:從微信 7.0.0 開始,可以通過判斷 userAgent 中包含 miniProgram 字樣來判斷小程序 web-view 環境。
使用 web-view 的話,請保證網頁中的微信 JSSDK 的版本大於 1.3.2 ,目前微信 JSSDK 的版本為 1.4.0,其升級了分享接口。所以如果要升級微信 JSSDK 到最新版本,請記得要升級 H5 頁面的分享接口。原有的 wx.onMenuShareTimeline、wx.onMenuShareAppMessage、wx.onMenuShareQQ、wx.onMenuShareQZone 接口,即將廢棄,取而代之的是 updateAppMessageShareData、updateTimelineShareData。最後新接口是拿不到分享成功失敗的信息的。
web-view 頁面向小程序通信
目前 web-view 網頁可通過 postMessage 向小程序發送信息,但是該信息只會在特定時機(小程序後退、組件銷燬、分享)觸發並收到消息。
小程序中通過在 web-view 中設置 bindMessage 屬性,收到信息,如下圖:
這對於 H5 分享轉小程序分享來說提供了一個非常靠譜的方案。如有些場景會引導用戶去分享(砍價、助力等),這樣點擊按鈕出現引導的時候,就得把原先 H5 頁面的分享信息傳向小程序。在小程序點擊分享的時候就會拿到 H5 頁面傳入的信息,再用這些信息構造分享即可。web-view 頁面中包括 iframe首先 iframe 的域名得為業務域名,不然頁面也會提示報錯,無法正常顯示。其次 iframe 的頁面裡面不能使用官網上所記載的相關接口1如果要在 iframe 中跳到其他小程序頁面的話,安卓可以使用window.top.window.wx.miniProgram.xxxAPI,而 IOS 中 window.top 是行不通的。頁面刷新要刷新頁面,得更新 web-view 的 src 屬性,即更新頁面的 URL,最簡單的方法就是加個時間戳參數。如詳細頁報名,報名成功回來就需要更新詳細頁報名信息。由於頁面返回觸發的是生命週期中的 onShow,所以需要在該函數中更新 URL 值。除此之外,如果 H5 頁面中有一些播放任務(音樂,視頻等),在頁面進入後臺的時候即 onHide 時候,應該需要把 URL 設置為空,不然音視頻會在後臺一直播放直至該小程序銷燬或者到音視頻結束調試 web-view開發工具調試在開發工具顯示面板,右鍵會出現調試,打開一個調試面板,當然這樣是看不到 cgi 請求的,要看請求我們得重新發送請求,如console裡面執行頁面刷新,或直接再次右鍵調試,都會觸發頁面刷新請求重新發送。
- 真機調試真機調試時,請保證開發工具上登錄的微信賬號與手機的賬號一致。不然可能會出現賬號問題(真機調試的賬號使用的是你開發工具上的賬號)。由於 web-view 組件的層級實在太高,蓋住了 vconsole 的調試,所以相當於沒有調試工具。不過也有一些辦法可以解決:如果其他上下關聯的頁面是非 web-view 的話,可以在上下關聯的頁面中查看 vconsole 的信息
- 使用 alert大法
- 使用 whistle(關於 whistle 如何調試下次再具體介紹)
總結
最後的最後,不論在開發工具中顯示良好或者不良好,都一定要用真機查看效果,而且 IOS 和 安卓都要看下。 不要太相信你的代碼,也不能不相信你的代碼
閱讀更多 程序弈說 的文章