美文网首页
公众号h5中使用微信JS-SDK(个人笔记)

公众号h5中使用微信JS-SDK(个人笔记)

作者: kevision | 来源:发表于2021-11-26 14:47 被阅读0次

    开发前必读:
    JS-SDK说明文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html

    通过使用微信JS-SDK,网页开发者可借助微信高效地使用拍照、选图、语音、位置等手机系统的能力,同时可以直接使用微信分享、扫一扫、卡券、支付等微信特有的能力,为微信用户提供更优质的网页体验。
    例子为在vue中使用微信JS-SDK,步骤如下:

    一、绑定域名

    先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”。
    备注:登录后可在“开发者中心”查看对应的接口权限。

    二、安装/引入文件

    插件方式:

    npm i weixin-js-sdk -S
    

    引入js文件方式:

    在需要调用JS接口的页面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.6.0.js
    如需进一步提升服务稳定性,当上述资源不可访问时,可改访问:http://res2.wx.qq.com/open/js/jweixin-1.6.0.js (支持https)。

    三、全局引入

    挂载到Vue原型

    // main.js
    import wx from 'weixin-js-sdk'
    Vue.prototype.$wx= wx
    // 开放标签属于自定义标签,Vue会给予未知标签的警告,可通过配置Vue.config.ignoredElements来忽略 Vue 对开放标签的检查
    Vue.config.ignoredElements = ['wx-open-launch-weapp']
    

    四、配置(包括js-sdk和开放标签)

    与使用 JS-SDK 配置方式相同,所有需要使用开放标签的页面必须先注入配置信息,并通过openTagList字段申请所需要的开放标签,否则将无法使用(同一个 url 仅需调用一次)。开放标签的申请和 JS 接口的申请相互独立,因此是可以同时申请的。

    mounted() {
        this.createJsapiSignature()
    }
    
          createJsapiSignature() {
                // 根据接口返回config信息
                this.$axios
                    .createJsapiSignature({
                        url: window.location.href.split('#')[0] // 注意:url必须为在安全域名下的页面全路径,
                                                                //hash之前的部分,否则会出现获取不到api权限的问题
                    }).then(res => {
                        let result = res.data.data
                        this.$wx.config({
                            debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,
                                          //可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                            appId: result.appId, // 必填,公众号的唯一标识
                            timestamp: result.timestamp, // 必填,生成签名的时间戳
                            nonceStr: result.nonceStr, // 必填,生成签名的随机串
                            signature: result.signature, // 必填,签名
                            jsApiList: ['chooseWXPay','chooseImage', 'previewImage'], // 必填,需要使用的JS接口列表
                            openTagList: ['wx-open-launch-weapp'] // h5跳小程序
                        })
    
                        this.$wx.ready(() => {
                            // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,
                            // config是一个客户端的异步操作,所以如果需要在页面加载时就调用相关接口,
                            // 则须把相关接口放在ready函数中调用来确保正确执行。
                            // 对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
                        })
                        this.$wx.error(function (res1) {
                            // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,
                            //也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
                        });
                    }).catch(err => {
                        console.log("err", err)
                    })
            },
    

    五、使用

    配置成功之后,就可以使用相关的api了。例子为微信支付。

            handlePayNow() {
                let that = this
                this.$axios.recharge({ // 调接口获取参数
                    payChannel: 2
                }).then(res => {
                    if(res.data.code==404) {
                        this.$toast(res.data.message)
                    }
                    else if(res.status==200) {
                        let result = res.data.data
                        let beanOrderId = result.beanOrderId
                        // 是否生成订单
                        this.beanOrderId = result.beanOrderId
                        if (result.result_code === "SUCCESS") {
                            this.$wx.chooseWXPay({ // 调起微信支付
                                timestamp: result.timestamp, // 支付签名时间戳,注意微信jssdk中的所有使用timestamp字段均为小写。但最新版的支付后台生成签名使用的timeStamp字段名需大写其中的S字符
                                nonceStr: result.nonce_str, // 支付签名随机串,不长于 32 位
                                package: result.package, // 统一支付接口返回的prepay_id参数值,提交格式如:prepay_id=***)
                                signType: 'HMAC-SHA256', // 签名方式,默认为'SHA1',使用新版支付需传入'MD5'
                                paySign: result.sign, // 支付签名
                                success: function (res) {
                                // 支付成功后的回调函数
                                    that.$toast('支付成功');
                                },
                                cancel: function(res) {
                                    // 取消付款
                                    if(res.errMsg && res.errMsg === 'chooseWXPay:cancel') {
                                        that.$axios.cancel({ id: beanOrderId }).then((res) => {
                                            if(res.data.status===200) {
                                                that.$toast('您已取消支付');
                                            }
                                        })
                                    }
                                    this.beanOrderId = ''
                                },
                                fail: function() {
                                    that.$toast('支付失败');
                                }
                            });
                        }
                    }
                }
            },
    

    六、关于分享功能的温馨提示

    1. onMenuShareTimelineonMenuShareAppMessageupdateAppMessageShareDataupdateTimelineShareData等一系列的分享功能,都只是自定义分享的内容,如链接地址,图片,描述等分享出去的卡片内容,并不能调起分享好友列表等功能,还是得用户自己点击右上角的三个点进行分享。

      image.png
    2. 如果新接口updateAppMessageShareDataupdateTimelineShareData不生效,不妨把旧接口onMenuShareAppMessageonMenuShareTimeline加到jsApiList中试试。

    this.$wx.config({
        debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
        appId: result.appId, // 必填,公众号的唯一标识
        appId: result.appId, // 必填,公众号的唯一标识
        timestamp: result.timestamp, // 必填,生成签名的时间戳
        nonceStr: result.nonceStr, // 必填,生成签名的随机串
        signature: result.signature, // 必填,签名
        jsApiList: ['updateAppMessageShareData', 'updateTimelineShareData', 'onMenuShareTimeline', 'onMenuShareAppMessage'], // 必填,需要使用的JS接口列表 , 
        openTagList: []
    })
    

    3.分享出去的是链接,不是卡片的原因及解决方案:
    原因:微信开放全域名访问后出现的限制。
    解决方法:

    1.将链接添加至公众号的自定义菜单中,从公众号菜单进入分享
    2.扫描二维码分享
    3.将链接保存至微信收藏中,从我的收藏进入分享
    其余其他地方进入分享都是链接形式

    1. 分享好友和朋友圈卡片的图标使用本地图片的方法:
    let img = require('@/assets/images/basics/shareImg.png')
    this.$wx.updateAppMessageShareData({
         title: '分享标题', // 分享标题
         desc: '分享描述', // 分享描述
         link: `${env.h5Link}activity`, // 分享链接
         imgUrl: env.h5Link.concat(img), // 分享图标使用本地图片:域名拼接图片路径
         success: (res) => {
             console.log('suceess', res)
         },
         fail: (err) => {
             console.log('err', err)
         }
    })
    
    1. h5分享好友和朋友圈,在hash模式下,分享出去的链接会把#后面部分去掉。如:
    配置的link: 'https://hds-h5-test.helloworld.cn/index.html#/input-account?wishId=59&activityId=1'
    实际分享出去的link: 'https://hds-h5-test.helloworld.cn/index.html'
    

    这会导致别人通过分享卡进来的页面不是自己配置的页面。
    解决办法:把路由hash模式改成history模式。(让后端把匹配不到的页面重定向到首页)

    七、关于保存图片的温馨提示

    1. 通过点击按钮创建a标签的方式来进行下载图片,在微信网页打开并不会执行,目前只能长按进行保存图片,微信jssdk目前没有提供相关api进行下载。

    八、关于模板消息、一次性订阅消息和订阅通知的温馨提示

    1. 模板消息
      只要关注了微信公众号获取到用户openid,公众号模板消息就可以针对这个用户主动进行消息推送。不需要用户形式上的授权,直接根据openid给用户发模板消息就行。官方的运营规范上,是要求用户必须主动跟你们产生交互(包括APP等其他场所),才能给用户发。实际操作,注意不要骚扰用户就行。一经投诉可能会得到微信官方处罚。

    2. 一次性订阅消息

    image.png

    开发者需要配合使用微信开放平台提供的 SDK 进行一次性订阅消息授权请求接入。正确接入 SDK 后,开发者移动应用会在终端本地拉起微信应用进行订阅消息授权 ,微信用户确认后微信将拉起开发者移动应用,并带上授权用户 openid 等信息。
    使用方式:引导用户打开https://mp.weixin.qq.com/mp/subscribemsg?action=get_confirm&appid=wxaba38c7f163da69b&scene=1000&template_id=1uDxHNXwYQfBmXOfPJcjAS3FynHArD8aWMEFNRGSbCc&redirect_url=http%3a%2f%2fsupport.qq.com&reserved=test#wechat_redirect链接。
    可拉起微信打开一次性消息订阅授权页:

    image.png
    1. 订阅通知
    image.png

    使用方式:

    1. 可以在图文消息、网页设置订阅通知组件。可通过公众号图文编辑器,在文章中插入订阅通知组件,文章推送后用户即可点击订阅。
    2. 也可以使用开放标签能力,服务号订阅通知按钮:wx-open-subscribe,在网页内设置订阅通知组件。
    image.png

    九、常见问题和注意事项

    网页授权注意事项:

    1. 在vue的hash模式下,授权完成后跳回redirect_uri,微信会把拿到的code, state参数拼接到url的中间,如:https://xxx.cn?code=xxx&state=xxx/#/activity,我们需要对url进行重新组装,再重定向到对的地址。
    2. redirect_uri参数需要使用urlencode进行编码。
    let uri = encodeURIComponent(env.redirect_uri)
    

    如需添加参数,可在redirect_uri后面进行拼接,授权成功之后会带回来。

    let uri = encodeURIComponent(`${env.redirect_uri}?id=1`)
    
    1. 授权地址去掉state, 用户拒绝授权可以重新调起授权
    window.location.href = `https://open.weixin.qq.com/connect/oauth2/authorize?
    appid=${env.appid}&redirect_uri=${uri}&response_type=code&scope=snsapi_userinfo
    #wechat_redirect`;
    

    当调jssdk的api报错时的注意事项:

    1. js接口安全域名是否配置。在正式开发之前就应该配置好相关安全域名,网页授权也需要配置对应的网页授权域名白名单。
    lQLPDhtJtchENfjNAzfNBhewWXYfiuWfcQcCSXCWpAATAA_1559_823.png
    1. 检查appid是否一致。接口获取到的appid和公众号后台的appid比对。
    image.png
    1. 服务器ip白名单是否有添加。在公众号后台查看,没有添加会导致api权限获取失败,apiList为空。
    image.png
    1. wx.config是否成功走到ready里面。走到ready里面才说明config配置成功。
    2. jsApiList是否填了需要调起的js接口。填写了相关接口,才能调起。
    3. 如果出现签名不合法的问题,在前端很可能是传给后端的url不对,因为后端就是通过url来生成对应的签名。url应为在配置的安全域名下的页面全路径,而且必须是动态的,一般是通过window.location.href.split('#')[0]获取,不要直接写死。

    其他问题请参考:https://www.jianshu.com/p/d343067b1ce6

    相关文章

      网友评论

          本文标题:公众号h5中使用微信JS-SDK(个人笔记)

          本文链接:https://www.haomeiwen.com/subject/kvjpwltx.html