2020-12-11

微信公众号跳转小程序所遇坑

根据微信开发者文档,满足以下条件就可以从网页公众号跳转指定小程序

微信版本要求为:7.0.12及以上。 系统版本要求为:iOS 10.3及以上、Android 5.0及以上

微信公众号跳转小程序文档

根据文档所说,跳转按钮格式为:

<wx-open-launch-weapp
id="launch-btn"
username="gh_******"
path="pages/index/index.html"
>
<script type="text/wxtag-template">
<style>.check_question{background-color: rgb(32,56,100);height: 25px;line-height: 25px;color: #fff;text-align: center;border-radius: 15px;padding: 0 10px;}</style>
<div class="check_question">点击查看</div>
</script>
</wx-open-launch-weapp>

说明:

  1. username是公众号的原始id,gh_开头的id,在微信公众平台可以找到
  2. path是需要跳转的小程序页面路径,记得带上.html,需要带参数就直接在后面加,跟url一样,问号传参
  3. 因为这里使用的是template,样式只能写在内部,否则无效~
  4. vue报template错误的话在man.js加上 Vue.config.ignoredElements = ['wx-open-launch-weapp']

引入微信js

<script src="//res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

然后配置wx.config,一般文档都有写的很清楚,后台返回所需要的信息,前端配置下就可以了,大概如下:

this.$http.get('/api/wechat/jsapi-signature?url=' + url).then(response => {
        if (response.success) {
          wx.config({
            debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
            appId: response.data.appId, // 必填,公众号的唯一标识
            timestamp: response.data.timestamp, // 必填,生成签名的时间戳
            nonceStr: response.data.nonceStr, // 必填,生成签名的随机串
            signature: response.data.signature, // 必填,签名
            jsApiList: ['wx-open-launch-weapp'], // 必填,需要使用的JS接口列表
            openTagList: ['wx-open-launch-weapp'] // 可选,需要使用的开放标签列表,例如['wx-open-launch-app']
          })
          that.getPredictList()
          // 通过ready接口处理成功验证
          wx.ready(function () {
            console.log('ready')
            // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中
          })
          // 通过error接口处理失败验证
          wx.error(function (res) {
            console.log(res)
            // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名
          })
        }
      })

这里说一个ios可能遇到的问题

很多时候,wx.config配置都正确,但是ios会出现进入页面的时候报invalid signature,签名是非法的,但是你刷新两次页面就会发现签名又成功了。会出现这个原因百分之九十是因为url的问题。具体分析参考一位网友的说明:

在IOS手机微信端,从A页面(http://a.com/A) 跳转到B页面(http://a.com/B)后,B页面进行分享时就会报签名(invalid signature)错误。
分析:
从A页面跳转到B页面时,由于是使用vue-router切换,都是操作浏览器历史记录,所以ios端微信浏览器锁定的url的还是A页面的url。

这个时候,是不是很多人都会认为,既然页面路由变化了,那我重新请求下url签名接口,不就可以了。呵呵呵,你会发现报错:invalid signature。但是再刷新一下,又没有签名问题,尼玛,这是什么原因呢???

那么你在请求url签名接口的时候,传递的url参数又是什么呢?大概如下吧:
url1、直接是 location.href (history模式)
url2、自己拼装的 location.origin + '/#' + this.$route.pullPath (hash模式)
这个时候,你请求的接口都没问题,也能拿到签名数据。但是

问题就出在:你所请求的url签名地址和浏览器执行jweixin-1.x.x.js时锁定的地址 不一致、不一致、不一致。你当前请求的可能是url1或url2,而此时微信锁定的地址仍然是进入A页面时的url(因为在进入A页面是加载并执行了jweixin-1.x.x.js, 而路由变化A到B时,并没有再次执行jxinwei-1.x.x.js)。所以问题就发生了,但是你再刷新一下,jweixin-1.x.x.js重新执行,此时微信浏览器锁定的url就是你当前刷新的url地址了,所以签名又成功了。
主要是因为:
【IOS】:ios微信端,路由变化时,微信认为SPA的url是不变的。
【Android】:android微信端,路由变化时,SPA的url是会变的(官方在安卓6.2版本,才对SPA变化作了支持)

所以,发起签名的url必须是微信锁定的url。

总的来说九十你发起的url跟微信签名的url不一样,解决方案就是进入页面的时候先锁定一个url,然后传递url的时候根据机器判断传哪一个。如下:

# router.js

router.beforeEach((to, from, next) => {
  if (/\/login\/*/.test(to.path)) {
    next()
  } else if (!sessionStorage.getItem('isLogin')) {
    next({ path: `/login?target=${to.path}` })
  } else {
    next()
  }

  if (typeof window.entryUrl === 'undefined' || window.entryUrl === '') {
    window.entryUrl = location.href.split('#')[0]
  }
})
# 对应page
 let url = ''
 let u = navigator.userAgent;
 let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
 if (isIOS) {
 url=window.entryUrl
 }else{
 url = window.location.href;
 }
 ...
 # 调用wx.config的参数接口

我项目里完整的例子如下:

# page
<template>
  <div id="home">
    <wx-open-launch-weapp
    id="launch-btn"
    username="gh_4d56729546a9"
    path="pages/index/index.html"
    >
    <script type="text/wxtag-template">
    <style>.check_question{background-color: rgb(32,56,100);height: 25px;line-height: 25px;color: #fff;text-align: center;border-radius: 15px;padding: 0 10px;}</style>
    <div class="check_question">点击查看</div>
    </script>
    </wx-open-launch-weapp>
  </div>
</template>

<script src="//res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script>
import Vue from 'vue'

export default {
  name: 'home',
  data () {
    return {
    }
  },
  created () {
    this.getSign()
  },

  methods: {
    getSign () {
      const that = this
      let wx = require('weixin-js-sdk')

      let url = ''
      let u = navigator.userAgent;
      let isIOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端
      if (isIOS) {
        url=window.entryUrl
      }else{
        url = window.location.href;
      }
      this.$http.get('/api/wechat/jsapi-signature?url=' + url).then(response => {
        if (response.success) {
          wx.config({
            debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印
            appId: response.data.appId, // 必填,公众号的唯一标识
            timestamp: response.data.timestamp, // 必填,生成签名的时间戳
            nonceStr: response.data.nonceStr, // 必填,生成签名的随机串
            signature: response.data.signature, // 必填,签名
            jsApiList: ['wx-open-launch-weapp'], // 必填,需要使用的JS接口列表
            openTagList: ['wx-open-launch-weapp'] // 可选,需要使用的开放标签列表,例如['wx-open-launch-app']
          })
          // 通过ready接口处理成功验证
          wx.ready(function () {
            console.log('ready')
            // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中
          })
          // 通过error接口处理失败验证
          wx.error(function (res) {
            console.log(res)
            // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名
          })
        }
      })
    }
  }
}
</script>
<style lang="scss" scoped>
  @import "home";
</style>

``

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,793评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,567评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,342评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,825评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,814评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,680评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,033评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,687评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,175评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,668评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,775评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,419评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,020评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,206评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,092评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,510评论 2 343