你所误解的微信公众号开发、以及微信公众号网页授权、接收url跳转参数等问题
关注公众号: 微信搜索 web全栈进阶
; 收货更多的干货
微信公众号
运行在微信终端的应用 (对于开发者来说比较爽的你只需考虑兼容微信浏览器,因为它是在微信内置浏览器环境下运行的)
微信公众号开发分为两部分:
一、传统开发(前后端分离) 推荐 页面量大的时候优点就尤其突出了
1. 微信首页
- 即首页菜单、跳转链接、扫二维码、消息推送回复等功能; 不要慌 这些百分之90%都是后台来配置的;
- 他们调用下微信公众平台提供的接口就ok了;为什么是后台配置呢因为交互方式是
web用户 --> 后台服务器/公众号服务器 --> 微信服务器
;
2. H5
部分
就是通过菜单跳转其他的页面皆为H5
的(说白了开发微信公众号前端主要负责的就是H5部分(就是和平常时开发移动端一模一样没区别))
二、node.js/H5
或者 php/h5
的话
那就不好意思了 以上全部都是自己搞
正题
这里介绍的是第一种开发模式
: 所谓的微信公众号开发前端就是负责移动端
而已 没什么不同的
-
个人觉得新项目开发
选好技术栈(框架、ui框架、适配、css预编译等)
重中之重,能节省很多的开发时间, -
小提示:移动端适配来说选用
px2rem
是最爽的适配,没有之一; 对于传统适配 怎么转换之类统统说白白, 插件自己会帮你转换
遇到的坑
遇到的坑如下: (主要说和微信相关的,移动端常见的坑这里就不多说了;若开发中遇到了可以留言)
1. vue hash
模式下携带参数网页授权后, 回调链接参数错乱
#
不知道跑到哪里去了; 导致参数获取不对。有一说一最开始的时候是没问题的,不知道微信什么时候改版之后就会有这问题了, 一脸懵逼; 这时我是手动处理参数的,还原正常的 跳转url
mounted () {
let httpUrl = decodeURI(window.location.href)
let url = httpUrl.replace('#/loginJudgement', '')
if (httpUrl.includes('com/?code')) { // url包括 com/?code 证明为从微信跳转回来的
let index = url.indexOf('com/') + 4 // 获取域名结束的位置
let urlLeft = url.substring(0, index) // url左侧部分
let urlRight = url.substring(index + 1, url.length) // url右侧去掉?部分
let result = urlLeft + '#/loginJudgement?' + urlRight.replace('?', '&')
console.log(result)
window.location.href = result
} else {
this.getUrlParams(decodeURI(window.location.href))
}
}
2、获取用户信息(openid、UnionID
、昵称、头像、性别、所在城市、语言和关注时间等等)
其中除UnionID
外 其他的主要通过网页授权均可获取 (网页授权具体操作将由下面的坑解释)
- 开发的时候获取用户信息什么都获取到了,但就差一个
UnionID
怎么试都获取不了 - 原因在于微信公众号一定要到微信公众开发平台绑定开放才能获取到
UnionID
; 这个坑因为没想到这个方向所以坑了蛮久的时间
3、通过网页授权获取 code
再通过 code
获取用户openid、UnionID
web
网页端要获取这两个信息只能通过 code
获取,后台获取的话就不同
- 获取
code
就要通过web
网页授权了 ; - 具体流程是 在
web
页面通过调用 微信提供的接口 发起授权;微信在把code
已回调链接的形式返回给你,这时你解析url
的参数就能拿到code
再传给后台
部分代码如下:
3.1、不携带参数的情况
mounted () {
// 获取路劲参数 静默授权不提示用户 scope=snsapi_base 非静默scope=snsapi_userinfo 询问操作 http 即官方提供的回调链接
// AppId 为微信公众号的 id httpUrl 为微信所配置的网页授权回调 网页授权回调域名即发布服务器后的项目 配置/查看步骤 最下面的接触权限 --> 网页授权获取用户信息 --> 点击修改 跳转到页面最下面即可看到网页授权域名设置
let http = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${window.AppID}&redirect_uri=${httpUrl}&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect`
window.location.href = http
},
3.2、带参数即从别的地方跳转要携带参数在页面显示 (主要思路是解析出要的参数在网页授权时传给微信,微信会和code
一起在传回给你)
mounted () {
// 获取路劲参数 静默授权不提示用户 scope=snsapi_base 询问操作 scope=snsapi_userinfo
this.getUrlParams(decodeURI(window.location.href))
},
methods: {
// 切割处理参数并跳转至网页授权
getUrlParams (url) {
let webpageUrl = window.webpageUrl
let http = url || 'https://www.baidu.com/#/sourceJudgement?source=3&businessId=$businessId×tamp=$timestamp'
let params = {}
http.replace(/([^?&=]+)=([^&]+)/g, (_, k, v) => params[k] = v) // eslint-disable-line
// 没有携带参数
if (JSON.stringify(params) === '{}') {
let httpUrl = encodeURIComponent(webpageUrl)
let http = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${window.AppID}&redirect_uri=${httpUrl}&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect`
window.location.href = http
} else { // 链接携带有参数
if (params && params.source) {
webpageUrl += '?'
Object.keys(params).forEach(function (key) {
webpageUrl += `${key}=` + `${params[key]}&`
})
webpageUrl = webpageUrl.substring(0, webpageUrl.length - 1)
}
// 跳转链接附带参数的情况下,需要一起组装并传给微信后台授权,微信后台回一起返回回来;暂存的方式是不行的,因为跳转过来的话相当于重新进入项目, 状态全部清空了, 除非用本地浏览器缓存起来
let httpUrl = encodeURIComponent(webpageUrl)
let http = `https://open.weixin.qq.com/connect/oauth2/authorize?appid=${window.AppID}&redirect_uri=${httpUrl}&response_type=code&scope=snsapi_userinfo&state=123#wechat_redirect`
window.location.href = http
}
}
通过上述回调最终微信端会回调上面httpUrl
页面 code
一参数形式传过来 只需解析出 code
保存下来就行
mounted () { // 切割 url 封装参数
let http = 'https://www.baidu.com/#/sourceJudgement?source=3&businessId=$businessId×tamp=$timestamp'
let params = {}
http.replace(/([^?&=]+)=([^&]+)/g, (_, k, v) => params[k] = v) // eslint-disable-line
console.log(params) // 参数对象 params.code 就是该用户的code 在传给后台 获取用户其他信息就行了
}
4、静默授权返回的code
去获取用户的 UnionID
会获取不到, 改为非静默授权, 即询问用户是否登录, 即可获取用户一切信息
5、页面返回到公众号首页 若你开启了eslint
则会报错 WeixinJSBridgeReady undefind
因为这个方法只在微信浏览器中有; 这时加上 eslint-disable-line
避免语法检查就行 项目在微信浏览器中没问题
methods: {
// 返回首页
goBack () {
if (typeof WeixinJSBridge === 'undefined') {
if (document.addEventListener) {
document.addEventListener('WeixinJSBridgeReady', this.onBridgeReady, false)
} else if (document.attachEvent) {
document.attachEvent('WeixinJSBridgeReady', this.onBridgeReady)
document.attachEvent('onWeixinJSBridgeReady', this.onBridgeReady)
}
} else {
WeixinJSBridge.call('closeWindow') // eslint-disable-line
}
},
onBridgeReady () {
WeixinJSBridge.call('hideOptionMenu') // eslint-disable-line
}
}
结尾
业务代码删除了一些, 有问题欢迎留言