微信JS-sdk使用
一、vue-router的hash模式和history模式的区别
- 路由模块的本质就是建立起url和页面之间的映射关系。
- hash和history改变URL的同时不会重新加载页面和发送请求。
hash
hash —— 即地址栏 URL 中的 # 符号。比如这个 URL:http://www.abc.com/#/hello hash 的值为 #/hello。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。
- url中有#
- 原理是onhashchange事件
- 仅 hash 符号之前的内容会被包含在请求中
- hash修改的url是同文档的url
- hash不会修改浏览器历史记录栈
- 生成二维码、微信分享页面的时候都会自动过滤掉#后面的参数
window.onhashchange = function(event){ console.log(event.oldURL, event.newURL); }
history
history —— 利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。
- url中没有#,美观
- 原理是popstate事件,浏览历史(即history对象)出现变化时,就会触发popstate事件。history.pushState用于在浏览历史中添加历史记录,history.replaceState修改浏览历史中当前纪录,但是并不触发页面刷新
- 全路径内容会被包含在请求中
- history修改的url可以是同域的任意url
- history会修改浏览器历史记录栈
- 刷新出现404
二、微信js-sdk授权失败解决方案
1、微信分享流程
① 进入某个页面后将该页面的 url 通过 sha1 算法加密后传给微信,微信会返回一个验证签名,这个签名是能否成功分享的关键。这里需要后端配合,前端无法独自完成。
② 在从后端拿到返回的签名配置后,需要调用 js-sdk 的 wx.config 将拿到的配置进行 js-sdk 的初始化。
③ 在 wx.config 初始化完成后需要调用 js-sdk 的 wx.ready 方法配置需要自定义的分享内容。
2、容易出问题的地方
大部分分享功能失败可能都是因为签名的原因,即提示 config:invalid signature ,这个错误一般都是由于 url 传递不正确导致的,当然也可能有其他的原因。
排查 url 错误
因为微信要求签名使用的 url 要是动态的,也就是说每次路由切换,url 改变的时候都需要重新签名,针对这个要求很容易就想到在全局的路由钩子里面来做处理。
一开始我是在 router.afterEach 钩子函数里面通过 location.href 来获取 url,我天真的以为在这里通过 location.href 获取到的 url 就是我们要进入的页面的 url,结果发现根本就不是的。
在 router.afterEach 中通过 location.href 拿到的 url 是要跳出的页面的 url 而不是要进入的页面的 url,可以通过下面的代码来自己观察下拿到的 url 具体是哪个:
router.afterEach((to, from) => { alert('to-----------' + to.fullPath) alert('from--------' + from.fullPath) alert('router-------' + location.href) })
url 可以通过域名加路由的方式拼接出来:
let url = location.origin + to.fullPath;
注意子域名
当使用了子域名时,需要把子域名也拼接上去,不然的话拼接出来的 url 肯定是不对的。比如我的子域名是 dc,那么就需要这样拼
location.origin + '/dc' + to.fullPath
3、history 和 hash 模式下使用代码
history模式下
ios的微信在vue使用history模式时,只能用第一次进入应用时的 url 去请求签名才能验证成功,这是因为Vue项目在切换页面时,IOS中浏览器的url并不会改变,依旧是第一次进入页面的地址,所以需要将第一次进入应用的 url 存起来,当路由变化时还是使用第一次的 url 去请求签名。
let _url; // 判断是否是ios微信浏览器 if (window.__wxjs_is_wkwebview === true) { _url = store.state.url; } else { _url = window.location.origin + '/mob' + to.fullPath; }
hash模式下
vue-router 默认采用的是 hash 模式,这种模式下路由后面会加上一个 # 号,在传给微信请求签名的时候需要把这个 # 去掉
let _url = window.location.href.split('#')[0];