记:微信小程序内嵌H5问题

上一节讲过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-routerhash模式,比如有一个链接如下(假设链接都可以访问):

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,然后结合我上方对应的中间页,就可以做好处理会跳首页的问题;

最后,不建议过多依赖于内嵌,内嵌只是解决一些基本的更新等问题,而不能作为主体功能,从功能性能和用户体验上都不是最优解;作为开发的我是一边口吐芬芳一边干着,痛苦并痛苦着,也算是搞完了;

posted @ 2021-06-04 18:02  sixth-rhapsody  阅读(2824)  评论(0编辑  收藏  举报