最近这里移动端项目把我整的头大,原因是因为甲方的需求,需要适配需要适配浙里办app需要适配城市大脑...一开始想也没啥,针对不同浏览器做不同的处理好了,但实际做出来的和想象的效果总是不尽如人意,总之里面的坑一言难尽。之前也写过关于浙里办的适配以及里面的坑点,这次就说说微信公众号上遇到的一些问题和处理情况,留个笔记下次好查阅。

依旧是上次的代码用的也是 vue 开发,当然这里用到的是 history 模式,因为要涉及到分享操作和其他微信 ssdk 处理。下面就把涉及到的一些比较麻烦的点列出来,针对解决;

  1. 微信端如何做的分享和分享需要操作的步骤和配置是怎么样的?
  2. 微信端如果分享出去的页面怎么点击返回按钮到首页?

针对微信上的配置可以直接上 官方文档 上看,详细阅读文档上的操作之后再进行下一步代码测试编写,代码中加上 wx.error() 报错查看。

如果出现错误应当按顺序排查问题;

  1. 是否是成功绑定了域名并且域名的校验文件可以被访问到。
  2. wx.config 的配置是否是正确无误,根据官网仔细检查单词的拼写和大小写。
  3. 需要访问的方法是否写在 jsApiList 中。
  4. 获取签名时的 URL 需要 encodeURIComponent 设置。
  5. 最重要的,后台的生成的签名的加密方法需要对照官方的文档设置,其中里面涉及到两次的获取数据的时间戳都是不同的,而且文档中也表明获取 code 必须在后端生存返回给前端,包括时间戳、字符串和 sign 签名。

另外在微信浏览器,前端如果做的是单页面开发的话,这时候安卓和苹果上的配置不一样的,具体是在调用 wx.xxx api 的时候会出错,处理这样的问题时需针对不同浏览器做不同的兼容(这里被坑了很长时间,查阅被坑过的同胞得知两边的处理是不同的...),具体问题出现的原因官方文档也有说明,如下;

目前Android微信客户端不支持pushState的H5新特性,所以使用pushState来实现web app的页面会导致签名失败,此问题已在Android6.2中修复

针对这个问题我们需要在代码中这样处理,这里我用的 vue 所以只对这个代码处理兼容,其他的自己考虑操作。
新建一个 share.js

WX20211117-172240.png

然后在 share.js 中可以这样写

import wx from 'weixin-js-sdk'
import { config } from 'api/config'
import { querySignature } from 'api/share'
import { Toast } from 'vant'
import { isIOS } from 'common/js/util'

// 根据传值唤起分享
export async function init() {
  // 对当前的 url 做一个处理
  const wx_localUrl = encodeURIComponent(window.location.href.split("#")[0])
  // 拿到后端返回的 sign 数据
  const res = await querySignature(wx_localUrl)

  wx.config({
    debug: false,
    appId: config.appId,
    timestamp: res.result.timestamp,
    nonceStr: res.result.noncestr,
    signature: res.result.signature,
    jsApiList: [
      'checkJsApi',
      'onMenuShareAppMessage',
      'onMenuShareTimeline'
    ]
  })
  wx.error(function(res){
    console.log(res)
  })
}

上面的代码只是针对进来的初始化设置,在不同的页面中去使用不同的微信 api 操作,比如说上面我写到了一个分享的接口。当我在首页下的二级页面需要分享的时候可以去调微信的分享方法 onMenuShareAppMessageonMenuShareTimeline 然后再点击微信右上角的点点按钮分享到其他人(这里说明一下,自从微信改版之后,所有的页面内的分享都必须走微信右上角的分享,不可以像之前点击就弹出分享页面,只有当点击页面分享之后,然后手动指引用户再去点击微信右上角的分享设置文字和图片路径等),具体使用方法如下;

// 简单的判断 是否是苹果微信浏览器
export function isIOS () {
  let isIphone = navigator.userAgent.includes('iPhone')
  let isIpad = navigator.userAgent.includes('iPad')
  return isIphone || isIpad
}

export function share(shareData) {
  // 这里是判断当前环境是否是 安卓还是苹果 做不同的设置
  if (!isIOS()) {
      init()
  }
  wx.ready(function () {
    const sharetitle = shareData.sharetitle || ''
    const sharedesc = shareData.sharedesc || ''
    const shareimg = shareData.shareimg || ''
    const linkUrl = shareData.sharelink || ''
    const type = shareData.type || ''
    wx.checkJsApi({
      jsApiList: ['onMenuShareAppMessage', 'onMenuShareTimeline'],
      success: function (res) {
        if (JSON.stringify(res.checkResult) === '{}') {
          return Toast.fail('微信调用失败')
        }
        if (type === 'friend') {
          wx.onMenuShareAppMessage({
            title: sharetitle,
            desc: sharedesc,
            link: linkUrl, 
            imgUrl: shareimg,
            success: function(res) {
              Toast.success('分享成功')
            }
          })
        } else if (type === 'circle') {
          wx.onMenuShareTimeline({
            title: sharetitle,
            link: linkUrl,
            imgUrl: shareimg,
            success: function(res) {
              Toast.success('分享成功')
            }
          })
        }
      }
    }) 
  })
}

接下来再来看自动登录的代码,在首页进来的时候我们是可以设置成自动进来就登录上的,然后确定登录成功之后就可以保存用户的信息和 token 信息,拿到这些就可以获取相应的数据了。
登录的时候需要注意事项有以下:

  • 需要把地址编码之后给微信端
  • 如果只需要 openid 的情况可以直接使用 snsapi_base 即可,这样不需要用户关注公众号免去点击确认登录
  • 记得确认 appid 和公众号的 appid 保持一致
  • 如果要回传参数可以在URL上带上 state 参数
  • 加上微信的 #wechat_redirect 无论直接打开还是做页面302重定向时候,必须带此参数
  • 最后一步使用 replace 方法跳转回首页,然后再通过返回的 code 请求后端拿到用户的信息

有了这些之后就可以直接拼出一个请求链接

const href = encodeURIComponent(window.location.href.split("#")[0])
const scope = 'snsapi_base'
const appid = config.appId
const url = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${href}&response_type=code&scope=${scope}#wechat_redirect`

window.location.replace(url)

做完上面的操作,那么你的微信ssdk配置和登录估计就没啥问题了,如果有那肯定是后端 sign 签名除了问题 ::(滑稽) (小声比比)。