小顺序如今愈来愈盛行,然则公司的许多项目都是用网页写的,小顺序语法不兼容原生网页,使得旧有项目迁移至小顺序价值很高;
小顺序之前开放了webview功用,能够说是网页运用的一大福音了,然则微信的webview有一些坑,这篇文章就是枚举一下我在开辟历程当中碰到的一些题目以及我找到的一些解决方案。
碰到的题目
openid登录题目
微信webview的运用要领很简单,只需以下设置src就能够展现详细的网站了。
<!-- wxml -->
<!-- 指向微信民众平台首页的web-view -->
<web-view src="https://mp.weixin.qq.com/"></web-view>
微信环境里的许多网页都是用页面要完成网站的登录功用,只需把登录的信息,比方openid或许其他信息拼接到src里就好了。
这里有个题目,民众号的账号体系平常是以openid来推断唯一性的,小顺序是能够猎取openid的,然则小顺序的openid和原民众号之类的openid是不一样的,须要将本来的openid账号体系晋级为unionid账号体系。
以下是微信对unionid的引见
猎取用户基本信息(UnionID机制)
在关注者与民众号发生音讯交互后,民众号可获得关注者的OpenID(加密后的微信号,每一个用户对每一个民众号的OpenID是唯一的。关于差别民众号,一致用户的openid差别)。民众号可经由过程本接口来依据OpenID猎取用户基本信息,包含昵称、头像、性别、地点城市、语言和关注时刻。
请注重,假如开辟者有在多个民众号,或在民众号、挪动运用之间一致用户帐号的需求,须要前去微信开放平台(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题目。
- 首先把要跳转的链接信息设置成全局变量,要改变src的时刻,先把要src以’?‘拆分为链接和参数两部份,存入全局函数,再挪用onLoad就能够完成webview革新了。
- 页面跳转时,我们也须要src的动态革新,所以要把链接信息存入全局函数;页面跳转时,onShow函数会被挪用,这时候刻再挪用一次onLoad就能够了。
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能够写成如许
<web-view src="{{url}}"></web-view>
付出功用
webview内里能够经由过程jssdk来完成一些小顺序功用,但不能直接挪用小顺序的付出功用,这时候刻我们就须要改变一下战略了:
- 在网页里引入微信jssdk
- 在网页须要提议付出的处所,挪用跳转页面的接口,掌握小顺序跳转到小顺序的付出页面(这个要在小顺序里零丁写的),跳转的时刻,须要把定单的一些信息都拼接到链接里,定单信息由背景返回,须要经由过程微信付出体系的一致下单接口,详细参看付出文档。
- 跳转到小顺序付出页面后,由小顺序页面提议付出,付出完成后跳转回webview页面,经由过程之前设置的动态src,掌握webview跳转到特定的页面。
// 网页引入jssdk
// 网页提议付出
wx.miniProgram.navigateTo({
// payData由背景返回,主如果须要一致下单平台的prepay_id
url: '../pay/index?data=' + encodeURIComponent(JSON.stringify(payData))
})
// 微信付出页面
onLoad: function (option) {
let page = this
try {
let data = JSON.parse(option.data)
if (!data || !data.prepay_id) {
console.error('付出参数毛病,请稍后重试', data)
}
wx.requestPayment({
timeStamp: '' + data.timestamp,
nonceStr: data.nonceStr,
package: 'prepay_id=' + data.prepay_id,
paySign: data.paySign,
signType: data.signType,
success: function (res) {
getApp().globalData.urlToken = `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地点的页面,假如须要加上页面参数,那我们就须要处置惩罚一下了。
- webview内是不能直接提议分享的,须要先用wx.miniProgram.postMessage接口,把须要分享的信息,推送给小顺序;推送给小顺序的信息不是实时处置惩罚的,而是用户点击了分享按钮以后,小顺序才归去读取的,这就请求每一个须要分享的页面再进入的时刻就提议wx.miniProgram.postMessage推送分享信息给小顺序。
- 小顺序页面经由过程bindmessage绑定的函数读取post信息,分享的信息会是一个列表,我们取末了一个分享就好,把分享信息处置惩罚好,存到data内里以便下一步onShareAppMessage挪用。
- 用户点击分享时,会触发onShareAppMessage函数,在内里设置好对应的分享信息就好了。
- onload函数有一个option参数的,能够读取页面加载时url里带的参数,这时候要对本来的onload函数举行革新,完成从option里读取链接信息。
// 网页wx.miniProgram.postMessage
wx.miniProgram.postMessage({
data: {
link: shareInfo.link,
title: shareInfo.title,
imgUrl: shareInfo.imgUrl,
desc: shareInfo.desc
}
})
// 小顺序index wxml设置
<web-view src="{{url}}" bindmessage="bindGetMsg"></web-view>
// 小顺序index js
bindGetMsg: 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
})
},
扫描平常二维码跳转特定页面
除了分享功用以外,小顺序还能够经由过程设置,完成扫描平常二维码跳转特定页面的功用。
以下是微信对此功用的引见
为了轻易小顺序开辟者更便利地推行小顺序,兼容线下已有的二维码,微信民众平台开放扫描平常链接二维码跳转小顺序才能。
功用引见
平常链接二维码,是指开辟者运用东西对网页链接举行编码后天生的二维码。
线下商户可不需替换线下二维码,在小顺序背景完成设置后,即可在用户扫描平常链接二维码时打开小顺序,运用小顺序的功用。
关于平常链接二维码,现在支撑运用微信“扫一扫”或微信内长按辨认二维码跳转小顺序.二维码划定规矩
依据二维码跳转划定规矩,开辟者须要填写须要跳转小顺序的二维码划定规矩。请求以下:
- 二维码划定规矩的域名须经由过程ICP备案的考证。
- 支撑http、https、ftp开首的链接(如:http://wx.qq.com、https://wx.qq.com/mp/、https://wx.qq.com/mp?id=123)。
- 一个小顺序帐号可设置不多于10个二维码前缀划定规矩。
前缀占用划定规矩
开辟者可挑选是不是占用相符二维码婚配划定规矩的一切子划定规矩。如挑选占用,则其他帐号不可请求运用满足该前缀婚配划定规矩的其他子划定规矩。
如:若开辟者A设置二维码划定规矩:https://wx.qq.com/mp?id=123,并挑选“占用一切子划定规矩“,其他开辟者将不能够设置满足前缀婚配的子划定规矩如https://wx.qq.com/mp?id=1234。
我引荐的体式格局
webview完成体式格局
设置跳转功用小顺序背景就能够设置,链接是分为四部份,路https://www.example.com/wxmin…。
https://www.example.com 域名 /wxmini/ 小顺序前置划定规矩,须要在服务器上建一个文件夹,而且把考证文件放在文件夹线 home.html 须要跳转的网页页面 a=1 跳转页面的参数 - 对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" // 毛病信息页面
],