H5嵌入微信小程序踩過的坑

關於背景

項目是一個涉及跨移動平臺的前端項目,技術使用的是vue,由於項目不是很大,因此沒有用到狀態管理。javascript

主要是用vue將h5項目編譯成靜態頁面放到服務器的制定地址上,而後在小程序測使用<web-view>,將服務器上的地址傳給這個標籤。css

關於遇到的坑

值傳輸的坑

由於使用的是<web-view>,根據個人理解,這個組件相似於html的<iframe>,但又沒有<iframe>成熟,不少屬性都沒法使用,基本的好比寬高。下面是<web-view>的屬性。html

屬性名 類型 默認值 說明
src String webview 指向網頁的連接。可打開關聯的公衆號的文章,其它網頁需登陸小程序管理後臺配置業務域名。 相似iframe的src
bindmessage EventHandler 網頁向小程序 postMessage 時,會在特定時機(小程序後退、組件銷燬、分享)觸發並收到消息。e.detail = { data }
bindload EventHandler 網頁加載成功時候觸發此事件。e.detail = { src }
binderror EventHandler 網頁加載失敗的時候觸發此事件。e.detail = { src }

上面主要有兩個屬性能夠傳值:前端

  1. src 經過url的屬性值傳值。
  1. bindmessage 經過h5頁面向小程序 postMessage 傳值。

第一個屬性遇到的坑: 總所周知,url的參數值裏不能存在=、?等奇怪的符號,否則會出現很奇怪的參數。好比 axxx.com?url=bxx.com?a=123最後拿到的url是什麼?確定不是bxx.com?a=123vue

解決辦法java

對要傳入<web-view>src中參數的值要進行encodeURIComponent(),而後在小程序中拿值是進行decodeURIComponent(),固然,這個須要小程序和H5雙方同步(若是小程序和H5是兩個項目組時)ios

第二個屬性遇到的坑: 這個坑屬於無心識的,沒有細看這個屬性的說明致使,因此看到的人請注意上面表格中加粗的位置,這個屬性看起來好像很方便,但小程序這邊並不是同步接收的,只有在小程序後退、組件銷燬、分享時觸發並收到消息css3

解決辦法web

若是是實時同步獲取數據的狀況,這個屬性並無什麼卵用。小程序

佈局的坑

這個也是爲何我會以爲<web-view>相似<iframe>但沒有<iframe>成熟的緣由了,<web-view>是全屏幕的,整個小程序頁面若是要用h5,那這個wxml就沒法放置更多的組件了,除非用wx:if。其實wx:if只是爲了控制這個頁面到底用h5仍是原生而已。

由於<web-view>佔滿了頁面,因此底部導航最後也只能在h5頁面中寫了,定位使用fixed。

遇到的坑:一、fixed佈局在小程序中的坑

忘記是ios仍是app中,當小程序中下拉和上劃時,整個頁面會看到小程序的容器。這裏瞭解一下小程序容器的結構。

<web-view>屬於 page內容,因此當在小程序中下拉時,會出現 backgroud部分覆蓋 <web-view>中定位爲 fixed的部分,以下圖,紅色文字區域部分被覆蓋了。

解決方法:

定位方式改成absolute,這個能夠解決覆蓋的問題,可是那一塊div會在page被上劃或者下拉時跟隨page移動,若是在<web-view>中使用小程序的導航,那麼整個導航條也會跟隨page移動。看使用場景,若是不介意這種狀況的可以使用這個解決,但介意的話,我這暫時也沒有更好的解決方法。若是有更好的解決方案,還望告知。

遇到的坑:二、內容高度未達到滿屏時沒法顯示底部的fixed佈局的div

在ios上,不管是h5嵌入小程序仍是app,都會出現這樣的問題。當內容高度不夠時,沒法顯示底層的div

解決方法:

頁面設置高度,使用css3vh特性

jssdk的坑--重點關於支付

若是你和我同樣,也是用的h5嵌入小程序,那麼能夠跳過在h5頁面上使用jssdk進行支付操做了,親測驗證不可行。一直堅信,既然h5能調jssdk接口,那麼必定可以調用支付接口。總在想,h5頁面直接調用支付,老是比h5與小程序交互去實現支付要簡單和方便的多。然而現實告訴我,不可行。緣由是由於signature一直報錯,後來查了以後,貌似是裏面生成signature的有個參數與小程序的不同。具體我也不是很清楚,若是有了解的還望告知一下。由於該方案並無成功實現微信支付的功能,因此暫不介紹使用方式。 還有一個可能的緣由是由於web-view組件中的h5頁面不支持支付接口,web-view網頁中僅支持如下JSSDK接口:

接口模塊 接口說明 具體接口
判斷客戶端是否支持js checkJSApi
圖像接口 拍照或上傳 chooseImage
預覽圖片 previewImage
上傳圖片 uploadImage
下載圖片 downloadImage
獲取本地圖片 getLocalImgData
音頻接口 開始錄音 startRecord
中止錄音 stopRecord
監聽錄音自動中止 onVoiceRecordEnd
播放語音 playVoice
暫停播放 pauseVoice
中止播放 stopVoice
監聽語音播放完畢 onVoicePlayEnd
上傳接口 uploadVoice
下載接口 downloadVoice
智能接口 識別音頻 translateVoice
設備信息 獲取網絡狀態 getNetworkType
地理位置 使用內置地圖 getLocation
獲取地理位置 openLocation
搖一搖周邊 開啓ibeacon startSearchBeacons
關閉ibeacon stopSearchBeacons
監聽ibeacon onSearchBeacons
微信掃一掃 調起微信掃一掃 scanQRCode
微信卡券 拉取使用卡券列表 chooseCard
批量添加卡券接口 addCard
查看微信卡包的卡券 openCard
長按識別 小程序圓形碼

以上並無能夠用的支付接口。若之後web-view除了支付接口,則大概能夠直接在h5頁面上進行支付操做而不用到小程序上操做了。

解決方法:

1.經過h5調用服務器接口獲取到支付所須要的參數(這些參數經過服務器去對接支付中心獲取到的)

這裏須要注意的是服務器獲取數據須要openid,而openid須要咱們傳下去,也就是在調用服務器接口前須要拿到openid。這裏的處理是在<web-view>的url中將openid做爲參數傳下去

2.將這些參數經過url跳轉到小程序,將參數傳到小程序頁面(須要新建一個小程序頁面)

跳轉使用的接口是wx.miniProgram.navigateTo,由於當支付失敗時須要返回原來的h5頁面,返回用的接口是wx.navigateBack,由於返回是在小程序中操做的。 舉個粒子,小程序中的頁面連接爲/page/pay/pay,那麼h5中進行跳轉的操做爲

const successUrl =encodeURIComponent('https://abc.com/successPage'); //支付成功頁
const path = `/page/pay/pay?timeStamp=${timeStamp}&nonceStr=${nonceStr}&package=${package}&signType=${signType}&paySign=${paySign}&successpage=${successUrl}`//?後面的參數都是支付須要的參數
wx.miniProgram.navigateTo({
   url: path
})
複製代碼

3.小程序頁面接受參數並執行支付操做。

小程序中的/page/pay/pay頁面中進行支付操做,該頁面有一個<web-view>組件,用來跳轉支付成功後的頁面也就是參數中的successpage

<web-view src='${url}' />
複製代碼
onLoad: function (options) {
    console.log(options)
    // 獲取網頁傳過來的值
    this.timeStamp = options.timeStamp
    this.nonceStr = options.nonceStr
    this.package = options.package
    this.signType = options.signType
    this.paySign = options.paySign
    this.successUrl = decodeURIComponent(options.successUrl)
    ...
  },
onReady: function(){
  wx.requestPayment({
    timeStamp: this.timeStamp,
    nonceStr: this.nonceStr,
    package: this.package,
    signType: this.signType,
    paySign: this.paySign,
    success (res) { 
        this.url = this.successUrl; //支付成功後會跳轉到h5的登錄成功頁
    },
    fail (res) { 
        wx.navigateBack();
    }
  })
}
複製代碼

關於wx.requestPayment,參見wx.requestPayment

這樣實現有一個缺點,就是當跳轉到小程序頁面進行支付時,頁面已經換掉了,再也不是原來的h5支付頁面了,解決也好解決,就是在小程序這邊實現一個一摸同樣的h5頁面視覺,但仍會出現頁面刷新跳轉的動做。

to be continued

以上,即是目前記得的全部的坑,後期若是再遇到別的坑,再補充

關於文檔

小程序開發文檔

jssdk文檔