小程序之前开放了webview功能,可以说是网页应用的一大福音了,但是微信的webview有一些坑,这篇文章就是列举一下我在开发过程中遇到的一些问题以及我找到的一些解决方案。
遇到的问题
openid登录问题
webview动态src
支付功能
分享功能
扫描普通二维码跳转特定页面
返回按钮缺失问题
openid登录问题
微信webview的使用方法很简单,只要如下设置src就可以展示具体的网站了。
微信环境里的很多网页都是用页面要实现网站的登录功能,只要把登录的信息,比如openid或者其他信息拼接到src里就好了。
这里有个问题,公众号的账号体系一般是以openid来判断唯一性的,小程序是可以获取openid的,但是小程序的openid和原公众号之类的openid是不一样的,需要将原先的openid账号体系升级为unionid账号体系。
以下是微信对unionid的介绍
获取用户基本信息(UnionID机制)
在关注者与公众号产生消息交互后,公众号可获得关注者的OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的。对于不同公众号,同一用户的openid不同)。公众号可通过本接口来根据OpenID获取用户基本信息,包括昵称、头像、性别、所在城市、语言和关注时间。
请注意,如果开发者有在多个公众号,或在公众号、移动应用之间统一用户帐号的需求,需要前往微信开放平台(http://open.weixin.qq.com)绑定公众号后,才可利用UnionID机制来满足上述需求。
UnionID机制说明:
开发者可通过OpenID来获取用户基本信息。特别需要注意的是,如果开发者拥有多个移动应用、网站应用和公众帐号,可通过获取用户基本信息中的unionid来区分用户的唯一性,因为只要是同一个微信开放平台帐号下的移动应用、网站应用和公众帐号,用户的unionid是唯一的。换句话说,同一用户,对同一个微信开放平台下的不同应用,unionid是相同的。
做完以上步骤,就可以调用小程序api wx.getUserInfo() 来获取用户信息了,此步骤需要进行后台信息解密过程,在此就不再赘述,结合小程序api文档操作就好。
获取到unioid之后,将unionid信息拼接到src就可以进行网页登录操作了(前提是网页可以用跳转链接的方式登录,类似公众号页面获取openid的形式)。
webview动态src
微信的webview有个坑的地方,不会动态的监听src的变化,这就造成了一个问题,要通过改变src实现页面跳转就不可以了。
我尝试了一些方法之后,找到了一个解决方案:
微信webview在页面load的时候会加载一次webview,我们就利用这个特性来实现动态src问题。
data: { url: ‘’, loaded: false}// 小程序js里的onLoad函数可以写成这样
onLoad: function () { this.setData({ url: getApp().globalData.urlToken
+ '?' + getApp().globalData.urlData })},changUrl: function () { getApp().globalData.urlToken = 'https://www.example.com' getApp().globalData.urlToken = 'a=1&b=2' // 直接调用onLoad,就会实现src的刷新 this.onLoad()},onShow: function () { if (!this.data.loaded) { // 第一次不运行 this.setData({ loaded: true }) return } // 直接调用onLoad,就会实现src的刷新 this.onLoad() }// wxml可以写成这样
支付功能
webview里面可以通过jssdk来实现一些小程序功能,但不能直接调用小程序的支付功能,这时候我们就需要转变一下策略了:
paySuccess.html
// 支付成功 getApp().globalData.urlData = ‘data=paySuccessData’ wx.navigateTo({ url: ‘/page/home/index’, }) }, fail: function (res) { getApp().globalData.urlToken = payError.html
// 支付失败 getApp().globalData.urlData = ‘data=payErrorData’ wx.navigateTo({ url: ‘/page/home/index’, }) }, complete: function (res) { } }) } catch (e) { console.error(‘支付错误’, e) } }webview内是不能直接发起分享的,需要先用wx.miniProgram.postMessage接口,把需要分享的信息,推送给小程序;推送给小程序的信息不是实时处理的,而是用户点击了分享按钮之后,小程序才回去读取的,这就要求每个需要分享的页面再进入的时候就发起wx.miniProgram.postMessage推送分享信息给小程序。
小程序页面通过bindmessage绑定的函数读取post信息,分享的信息会是一个列表,我们取最后一个分享就好,把分享信息处理好,存到data里面以便下一步onShareAppMessage调用。
用户点击分享时,会触发onShareAppMessage函数,在里面设置好对应的分享信息就好了。
onload函数有一个option参数的,可以读取页面加载时url里带的参数,这时要对原先的onload函数进行改造,实现从option里读取链接信息。
// 网页wx.miniProgram.postMessagewx.miniProgram.postMessage({ data: { link: shareInfo.link, title: shareInfo.title, imgUrl: shareInfo.imgUrl, desc: shareInfo.desc }})// 小程序index wxml设置// 小程序index jsbindGetMsg: function (e) { if (!e.detail) { return } let list = e.detail.data if (!list || list.length === 0) { return } let info = list[list.length - 1] if (!info.link) { console.error(‘分享信息错误’, list) return } let tokens = info.link.split(’?’) this.setData({ shareInfo: { title: info.title, imageUrl: info.imgUrl, path: /page/index/index?urlData=${encodeURIComponent(tokens[1])}&urlToken=${tokens[0]}
} })},onShareAppMessage: function (res) { if (res.from === ‘button’) { // 来自页面内转发按钮 console.log(res.target) } let that = this return { title: that.data.shareInfo.title, path: that.data.shareInfo.path, imageUrl: that.data.shareInfo.imageUrl, success: function (res) { // 转发成功 }, fail: function (res) { // 转发失败 } }},onLoad: function (option) { if (option.urlToken) { getApp().globalData.urlToken = option.urlToken } if (option.urlData) { getApp().globalData.urlData = option.urlData } this.setData({ url: getApp().globalData.urlToken + ‘?’ + getApp().globalData.urlData })},
扫描普通二维码跳转特定页面
除了分享功能之外,小程序还可以通过配置,实现扫描普通二维码跳转特定页面的功能。
以下是微信对此功能的介绍
为了方便小程序开发者更便捷地推广小程序,兼容线下已有的二维码,微信公众平台开放扫描普通链接二维码跳转小程序能力。
功能介绍
普通链接二维码,是指开发者使用工具对网页链接进行编码后生成的二维码。
线下商户可不需更换线下二维码,在小程序后台完成配置后,即可在用户扫描普通链接二维码时打开小程序,使用小程序的功能。
对于普通链接二维码,目前支持使用微信“扫一扫”或微信内长按识别二维码跳转小程序.
二维码规则
根据二维码跳转规则,开发者需要填写需要跳转小程序的二维码规则。要求如下:
https://www.example.com -> 域名
/wxmini/ -> 小程序前置规则,需要在服务器上建一个文件夹,并且把验证文件放在文件夹线
home.html -> 需要跳转的网页页面
a=1 -> 跳转页面的参数
2. 对onload函数再进行处理,实现普通二维码跳转。
// 对index onLoad在进行处理onLoad: function (option) { this.resetOption(option) if (option.urlToken) { getApp().globalData.urlToken = option.urlToken } if (option.urlData) { getApp().globalData.urlData = option.urlData } this.setData({ url: getApp().globalData.urlToken + ‘?’ + getApp().globalData.urlData })},resetOption: function (option) { if (!option) { return } if (option.q) { option.q = decodeURIComponent(option.q) if (option.q.indexOf(‘https://www.example.com/wxmini/’) == -1) { return } let tmp = option.q.replace(’/wxmini’, ‘’) let tmps = tmp.split(’?’) option.urlToken = tmps[0] option.urlData = tmps[1] } else { option.urlData = decodeURIComponent(option.urlData) }}
返回按钮缺失问题
如果web页面是在第一个页面的话,这时候会有一个问题,小程序的返回按钮就没有了,webview无法使用微信的返回按钮了,这时候只要在webview页面前多加一个跳转页面就好了(第一个页面也可以设置成获取用户权限的页面,不过我感觉这样体验不好,也不是所有页面都要用户获取了权限才可以使用)
最终的页面层级
“pages”: [ “page/index/index”, // 首页,处理onload里的option内容,为了返回按钮设置的 “page/home/index”, // webview所在的页面 “page/auth/index”, // 获取用户权限的页面 “page/pay/index”, // 支付页面 “page/error/index” // 错误信息页面 ],
https://www.jianshu.com/p/ab40bbc7eba0