详解Vue微信公众号开发踩坑全记录


Posted in Javascript onAugust 21, 2017

本文介绍了Vue微信公众号开发踩坑全记录,分享给大家,也给自己留个笔记。

需求

  • 微信授权登录(基于公众号的登录方案)
  • 接入JS-SDK实现图片上传,分享等功能

现状及难点

  • 采用的Vue框架,前后端分离模式(vue工程仅作为客户端),用户通过域名访问的是客户端,但是微信授权中涉及签名和token校验依赖服务端
  • JS-SDK需要向服务端获取签名,且获取签名中需要的参数包括所在页面的url,但由于单页应用的路由特殊,其中涉及到IOS和android微信客户端浏览器内核的差异性导致的兼容问题

解决方案

授权登录

授权流程如下:

详解Vue微信公众号开发踩坑全记录

详细说明:

  1. 用户访问网站主域名
  2. vue客户端(domain/)接收请求,在路由解析前判断用户是否登录(比如检查cookie);
  3. 如果没有登录,则通过api获取微信授权地址,获取后跳转到微信服务端授权页面;
  4. 用户确认授权,微信服务器发起回调请求,这时需要回调到服务器端(domain/api/xxx)
  5. 服务器端保存用户信息,进行注册登录操作(记录cookie),重定向到vue客户端(domain/)
  6. 重复第一步,授权登录成功

踩坑记录:

以下是一个错误授权方案

详解Vue微信公众号开发踩坑全记录

这个方案为什么错误呢?其实如果只实现授权登录到话,这个方案是可以的,而且也很清晰,vue客户端单方面在服务器和微信服务器之间进行通信,微信服务器不能直接和服务器通信。这种方案的坑在于当微信授权回调时会携带一个code参数,该参数会污染vue路由导致ios上进行JS-SDK签名时失败(后续会具体描述这个问题)

JS-SDK签名

对于签名,官方是这么说的

所有需要使用JS-SDK的页面必须先注入配置信息,否则将无法调用(同一个url仅需调用一次,对于变化url的SPA的web app可在每次url变化时进行调用

vue中路由有history和hash两种模式;在history模式下,理想的设计方案是,当进入到需要用到JS-SDK组件时,获取以下当前url(也就是通过 location.href.split(‘#')[0]获得到的地址)传递到服务端进行签名,应该就没问题了,但是IOS获取的url并不是调用微信js的时候所在页面的地址,而是进入到网站第一个页面的地址。

网上查询到一个方案是针对ios设备进入页面时先将当前url记录下来,到授权页面时将记录的url传递给服务端进行签名。该方案经实践是可行的,妈妈再也不用担心我的网址很丑很难看啦。

另外一个方案就是使用hash模式,这种模式下,url永远都只是主域名地址,省去了传递url的烦恼,也没必要处理兼容,所以如果不建议路由中有#的话,该方案应该是首选方案。

这里还有一个深坑,那就是如果授权方案采用了上述中的vue客户端处理回调的方式,那么ios将永远无法签名成功,为什么呢,因为这种方案路由通常是这样子的:

http://domain.com/?code=xxxxxx&stat=#/xxx

这种路由中带了参数的url是没法签名校验成功的!
这种路由中带了参数的url是没法签名校验成功的!
这种路由中带了参数的url是没法签名校验成功的!
重要的事情得说三遍啊

Coding

任何不上代码的吹逼都是耍流氓,这里笔者分享下在vue中具体怎么coding的。

微信授权登录

笔者在项目中使用的vue-router进行路由控制,使用了vuex记录用户登录信息,但是由于vuex中存储的内容在页面刷新后会丢失,所以服务端同时也写了用户登录状态到cookie中,vue中需要通过这两个条件进行登录判断,不多BB,直接看代码吧

// ... other code

router.beforeEach((to, from, next) => {
 if ((!VueCookie.get('user') && !store.state.userInfo)) {
  // 第一次访问
  console.log('授权登录')
  // 跳转到微信授权页面,微信授权地址通过服务端获得
  axios.post('/api/login').then(res => {
   var data = res.data
   if (data.code === 100) {
    window.location.href = data.data
   }
  })
 } else if (!store.state.userInfo) {
  // 刷新页面,获取数据存入vuex
  axios.get('/api/currentuser').then(res => {
   if (res.data.code === 100) {
    store.dispatch('setUserInfo', res.data.data)
    next()
   }
  })
  console.log('cookie生效期内登录')
  next()
 } else {
  // 已经登录
  console.log('已登录')
  next()
 }
})

//... other code

history模式下的JS-SDK签名

在入口文件中将当前url存入vuex

// ... other code
router.beforeEach((to, from, next) => {
 document.title = to.meta.title
 // 处理jssdk签名,兼容history模式
 if (!store.state.url) {
  store.commit('setUrl', document.URL)
 }
 // ... other code

在需要获取签名的组件中获取并进行配置

// ... other code
created () {
   var sef = this
   var url = ''
   // 判断是否是ios微信浏览器
   if (window.__wxjs_is_wkwebview === true) {
    url = this.$store.state.url.split('#')[0]
   } else {
    url = window.location.href.split('#')[0]
   }
   this.$http.get('/api/jssdk?url=' + url).then(function (res) {
    sef.lists = res.data.data
    hmTools.wechact(sef.lists, sef) //js-sdk配置
   })
  }
// ...other code

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js实现页面打印功能实例代码(附去页眉页脚功能代码)
Dec 15 Javascript
JQuery 选择器 xpath 语法应用
May 13 Javascript
javascript 进阶篇3 Ajax 、JSON、 Prototype介绍
Mar 14 Javascript
js+xml生成级联下拉框代码
Jul 24 Javascript
js格式化金额可选是否带千分位以及保留精度
Jan 28 Javascript
JS动态改变表格边框宽度的方法
Mar 31 Javascript
jQuery获取及设置表单input各种类型值的方法小结
May 24 Javascript
分享JavaScript监听全部Ajax请求事件的方法
Aug 28 Javascript
js-FCC算法-No repeats please字符串的全排列(详解)
May 02 Javascript
Vue.js用法详解
Nov 13 Javascript
koa+jwt实现token验证与刷新功能
May 30 Javascript
vue+element UI实现树形表格
Dec 29 Vue.js
前端图片懒加载(lazyload)的实现方法(提高用户体验)
Aug 21 #Javascript
Vue编写多地区选择组件
Aug 21 #Javascript
使用vue制作FullPage页面滚动效果
Aug 21 #Javascript
详解Layer弹出层样式
Aug 21 #Javascript
JS数组操作之增删改查的简单实现
Aug 21 #Javascript
JS实现评价的星星功能
Aug 20 #Javascript
详解A标签中href=""的几种用法
Aug 20 #Javascript
You might like
基于文本的访客签到簿
2006/10/09 PHP
php从数组中随机抽取一些元素的代码
2012/11/05 PHP
用Json实现PHP与JavaScript间数据交换的方法详解
2013/06/20 PHP
phpMyAdmin通过密码漏洞留后门文件
2018/11/20 PHP
静态的动态续篇之来点XML
2006/12/23 Javascript
js下获取div中的数据的原理分析
2010/04/07 Javascript
jquery学习笔记二 实现可编辑的表格
2010/04/09 Javascript
一个JQuery写的点击上下滚动的小例子
2011/08/27 Javascript
jQuery自动切换/点击切换选项卡效果的小例子
2013/08/12 Javascript
JS判断字符串包含的方法
2015/05/05 Javascript
jquery超简单实现手风琴效果的方法
2015/06/05 Javascript
浏览器环境下JavaScript脚本加载与执行探析之defer与async特性
2016/01/14 Javascript
Angularjs---项目搭建图文教程
2016/07/08 Javascript
JavaScript中ES6 Babel正确安装过程
2016/07/18 Javascript
让浏览器崩溃的12行JS代码(DoS攻击分析及防御)
2016/10/10 Javascript
js 文字超出长度用省略号代替,鼠标悬停并以悬浮框显示实例
2016/12/06 Javascript
使用get方式提交表单在地址栏里面不显示提交信息
2017/02/21 Javascript
如何给ss bash 写一个 WEB 端查看流量的页面
2017/03/23 Javascript
详解Vue 事件驱动和依赖追踪
2017/04/22 Javascript
微信小程序 蓝牙的实现实例代码
2017/06/27 Javascript
python中合并两个文本文件并按照姓名首字母排序的例子
2014/04/25 Python
浅谈python字符串方法的简单使用
2016/07/18 Python
python SocketServer源码深入解读
2019/09/17 Python
Python3 合并二叉树的实现
2019/09/30 Python
利用Tensorflow的队列多线程读取数据方式
2020/02/05 Python
什么是python的自省
2020/06/21 Python
马来西亚网上美容店:Hermo.my
2017/11/25 全球购物
UGG美国官网:购买UGG雪地靴、拖鞋和鞋子
2017/12/31 全球购物
餐饮业经理竞聘演讲稿
2014/01/14 职场文书
网上签名寄语活动留言
2014/01/18 职场文书
社区七一党员活动方案
2014/01/25 职场文书
新闻编辑自荐书范文
2014/02/12 职场文书
竞选学生会演讲稿
2014/04/25 职场文书
副总经理任命书
2014/06/05 职场文书
创业计划书之美容店
2019/09/16 职场文书
mysql升级到5.7时,wordpress导数据报错1067的问题
2021/05/27 MySQL