上一節講過App內嵌H5解決了一系列問題,基本上大多數遇到的問題都能夠解決,這節就說一下微信小程序內嵌H5問題,由於小程序的約束很大,小程序的webview使用時和微信公眾號差不了多少,小程序的webview對比使用App內嵌來說小程序的權限限制太多了,只能在進入頁面和出頁面才能傳遞數據,所以這時可以以小程序的webview為主導,小程序本身功能為輔來進行內嵌(我這邊需要快速輸出,不得已而為之),但是也遇到了一些問題:
- 由於小程序本身可以授權手機號碼,而公眾號無此功能,所以就以小程序做了登錄授權,那么如何讓小程序的登錄信息同步到內嵌的H5呢(這里不按照App的方式,這種webview鏈接不安全);
- 由於公眾號有自身的一套支付功能,但小程序本身也有一套支付功能,但是這兩套竟然不通,這里強烈吐槽,那么如果內嵌的H5要走支付就需要調起小程序的支付,但是后續流程就截斷了,如何處理;
- 微信小程序是可以根據對應內嵌頁面url來進行處理跳轉到對應的內嵌H5頁面的,但是這個時候返回按鈕是沒有的,如何處理返回到首頁呢;
- 由於公眾號的本地緩存和小程序所用的不是一套,不過它們webview的緩存是一套的,現在一個場景:用戶在公眾號登錄過,小程序內嵌的有些頁面不需要登錄授權的就可以進入,從其他渠道進入到小程序內嵌的一個不需要登錄授權的頁面,小程序的登錄憑證已過期,如何處理在不需要登錄的這個頁面跳轉時進行微信小程序登錄授權
一.小程序登錄授權給內嵌H5
其實這里可以用一個技巧,不過也需要后端的配合,當微信小程序登錄后,使用get請求接口,攜帶登錄信息,讓接口重定向到對應頁面,這時這個頁面就已經有了對應的登錄token;
二. 支付跳轉和外部跳轉返回問題
場景是這樣的,如果有一個流程是需要走支付,但是微信公眾號自己的支付是不能夠在微信小程序內嵌webview中支付的,這時候就需要借助跳轉到微信小程序的頁面進行支付,走微信小程序的支付流程后再跳轉到內嵌的頁面,但是從這里就會被截斷了,之前的頁面就會丟失,且無法返回到首頁。
這時想到了一種辦法,我們創建一個通用的中間頁,用於承載一些頁面進行從中間插入的截斷性操作,在中間頁中寫入一個本地緩存的標記:
<template lang="pug">
.middlepage-body
</template>
<script>
export default {
data () {
return {
storageKey: 'middlePageKey',
type: this.$route.query.type,
goNextUrl: ''
};
},
mounted () {
this.goNextUrl = this.$route.query.goNextUrl ? window.decodeURIComponent(window.atob(this.$route.query.goNextUrl)) : '';
this.checkUrl();
},
methods: {
checkUrl () {
const key = window.localStorage.getItem(this.storageKey);
console.log('檢測到' + this.storageKey + '的storageKey', key);
if (key) {
window.localStorage.removeItem(this.storageKey);
let href = window.location.origin + '/home/index';
window.location.replace(href);
} else {
window.localStorage.setItem(this.storageKey, '1');
if (this.goNextUrl) {
if (this.type === 'akey') {
// 處理一些業務
}
if (this.type === 'bkey') {
// 處理一些業務
}
this.$router.push(this.goNextUrl);
}
window.localStorage.removeItem(this.storageKey);
let href = window.location.origin + '/home/index';
window.location.replace(href);
}
}
}
};
</script>
<style lang="sass" scoped>
.middlepage-body
width: 100vw
height: 100vh
background-color: #fff
</style>
以上代碼,我們有一個中間頁,所有的跳轉都往中間頁跳轉,由中間頁首先保存一個緩存狀態storageKey
,第一次進入時無法獲取的,這時會自動跳轉到對應的業務goNextUrl
中,當用戶如果想回退,這時回退到中間頁,中間頁判定緩存狀態存在,則重定向到首頁,只要是能回退到首頁或者其他tab頁面就行(若想回退到支付之前的應該是不行的),也比較適用外部跳轉到內嵌的一個頁面,返回正好能達到首頁;但是這種有個問題,如果第一次從外部(這個外部可以是其他瀏覽器)跳轉進入,然后我再從外部跳轉進入,那么會出現頁面跳轉回首頁了,這種暫時還未有解決方案,除非用原生小程序實現,只能說項目就這樣,沒得辦法
三. 最后一個問題 (字太長不再粘過來,問題在文章開頭)
這里針對vue SPA設置的vue-router
為hash
模式,比如有一個鏈接如下(假設鏈接都可以訪問):
A. https://www.test.com/#/home/index
B. https://www.test.com/?hasauto=0#/home/index
只要是A鏈接能打開,B鏈接也能打開,只是B鏈接中間加入了一個參數,而且根據vue-router的hash模式規則,只會改變hash值來切換頁面,對於?hasauto=0
如果我們只使用vue-router提供的方法單頁面跳轉,是不會被清除的,如果使用window.location
的一些跳轉方法,且沒有加入?hasauto=0
就會被清除;
我們就可以采取上方這種在hash # 前加入自定義的一些參數,也不用在url后加入參數,然后在跳轉時的vue-router鈎子函數beforeEach
中做處理,如果是對應頁面,且存在hashauto=0
的參數就跳轉到對應的小程序授權頁面,需要攜帶下一個頁面的url,然后結合我上方對應的中間頁,就可以做好處理會跳首頁的問題;
最后,不建議過多依賴於內嵌,內嵌只是解決一些基本的更新等問題,而不能作為主體功能,從功能性能和用戶體驗上都不是最優解;作為開發的我是一邊口吐芬芳一邊干着,痛苦並痛苦着,也算是搞完了;