js控制URL地址的改变,以微信服务号的授权获取用户的昵称和头像为例
当遇到某个场景需改变当前的URL的时候,有以下几种方法
window.location = "http://service.gaotianyue.com/moon/index.html?openid="+openid;
window.history.pushState({},0,'http://service.gaotianyue.com/moon/index.html?openid='+openid);
window.history.replaceState({},0,'http://service.gaotianyue.com/moon/index.html?openid='+openid);
第一种,是重定向,浏览器会求再次请求(例如微信内置浏览器读条两次)。按回退键会再次请求,总之需要按两次才能退出页面
第二种,URL地址静默变化了,没有重新请求,需要按两次退出页面,第一次回退是到URL变化之前的页面,不读条。第二次退出页面。
第三种(用这个),打开页面只读条一次,只是URL地址变化了 ,回退一次就退出页面。
应用场景,
比如某个活动,发给微信用户moon/index.html,用户打开地址后需要跳转到微信授权接口,腾讯回调到你的服务器,你的服务器通过,微信的接口,获得了openid,nickname,头像,然后让微信用户重定向到moon/index.html?openid=XXX,然后前端使用openid来通过ajax来获取昵称和头像。
这个流程有个小问题,用户每次打开moon/index.html的时候,进度条要读好几次(跳转到后台授权,跳转到腾讯授权,跳转到moon/index.html?openid=XXX,然后用openid请求昵称和头像)。
解决的方式是用本地存储记录openid
var openid = s.getQuery("openid");if(!openid){//尝试从本地缓存中获取if(localStorage.opid){openid = localStorage.opid;}else{window.location = 'http://service.gaotianyue.com/moon/shouquan';return;}}
但是这个活动,有个进一步的需求,当你分享出去后,要知道是谁分享给你的。
经过测试,分享出去的链接,再次打开后,会有个installedApp=0这个参数,这样的话,我们可以判断这个参数是否存在,
从打开别人的分享链接
moon/index.html?openid=YY&installedApp=0
然后层层授权后返回
moon/index.html?openid=XX&srcopenid=YY
这就要保证别人发过来的链接是moon/index.html?openid=YY而不是moon/index.html。
因此我们每次从本地存储取得自己的openid后,要改变自己的网页URL。这样分享出去带着自己的openid。
这里就用到了我们总结的更改URL地址的第三种方法。静默改变自己的URL,但是重新请求。而且打开别人分享过来的链接后,也可以判断本地存储,
从打开别人的分享链接
moon/index.html?openid=YY&installedApp=0
直接修改URL为
moon/index.html?openid=XX&srcopenid=YY
这样不用任何跳转就能知道此页面是从谁分享过来的,是谁打开的。
因为腾讯授权获取头像,需要3步,一步是和客户端跳转获取一个code传到你的后台,一步是获取token和openid,还有次是获取昵称和头像。每个接口140毫秒左右,加上你一开始请求后台来控制跳转,这3~4步比较费时,用户感觉你的微信在反复读条。所以本文的处理还是减少了不少开销。之后不管是打开别人的分享链接还是打开主页,都是
只有一次请求,读条一次。
另外静默改变URL后,你右击微信右上角的。。。选择copyURL,拷贝的是moon/index.html,而不是moon/index.html?openid=XX。这不影响我们的逻辑,而且也正好避免了用户用这种分享出去后暴露自己的信息的情况。
下面是示例代码。
服务器:
@RequestMapping("/shouquan")public void sq(HttpServletRequest req, HttpServletResponse resp) throws IOException {String code = req.getParameter("code");// 如果无此参数,但是有state参数说明用户没有授权String srcOpenid = req.getParameter("state");// 提前放在腾讯回调的参数,放的是发朋友圈者的openidLogCore.BASE.debug("code={},state={},code is null?{},state is null?{}", code, srcOpenid, null == code,null == srcOpenid);/** code非空说明是授权传腾讯后过来的 */if (Util.nonNull(code)) {String[] tokenOpenid = OauthManager.inst().getAccessTokenAndOpenid(Constant.DEFAULT_APP_ID,Constant.DEFAULT_APP_SECRET, code);String accTokn = tokenOpenid[0];String openidSq = tokenOpenid[1];// 授权后的自己的openid// 通过缓存实现减少授权请求String[] infos = MoonManager.inst().getNickNamePic(openidSq);if (Util.isEmpty(infos)) {// 缓存中没有String[] accProfile = OauthManager.inst().getAccountProfile(accTokn, openidSq);// 授权失败的情况[null, null, {"errcode":48001,"errmsg":"api unauthorized, hints: [ req_id: EMvfbA0407ns86 ]"}]String profileSq = accProfile[2];// 全部信息的json字符串if (profileSq.contains("errcode")) { // 静默授权获取用户信息失败shouquan(resp, SNSAPI_USERINFO, srcOpenid);// 强制授权LogCore.BASE.info("force the auth start!{}", openidSq);return;}MoonManager.inst().setNickNameAndPic(openidSq, accProfile);}else{LogCore.BASE.info("hit the cache success!openid={},nickname={}", openidSq, infos[0]);}if (Util.isEmpty(srcOpenid) || MoonManager.inst().isHasHelped(openidSq, srcOpenid)) {resp.sendRedirect(Util.format("/moon/index.html?openid={}", openidSq));return;}// 如果是分享过来的resp.sendRedirect(Util.format("/moon/index.html?openid={}&srcopenid={}", openidSq, srcOpenid));return;}/**以下说明是客户端请求的授权 */String openid = req.getParameter("openid");// 带此参数说明是客户端请求的,shouquan(resp, SNSAPI_BASE, openid);// openid可能为null,即用户点进空白页面后授权}/*以放在客户端*/private void shouquan(HttpServletResponse resp, String scope_, String stateP) {String redirect_uri = URLEncoder.encode(WECHAT_SIGNON_CALL_BACK_URL);String response_type = "code";String path = null;String url = null;if (Util.isEmpty(stateP) || "null".equals(stateP)) {// 防止客户端获取空的openid后请求授权path = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={}&redirect_uri={}&response_type={}&scope={}#wechat_redirect";url = Util.format(path, Constant.DEFAULT_APP_ID, redirect_uri, response_type, scope_);} else {path = "https://open.weixin.qq.com/connect/oauth2/authorize?appid={}&redirect_uri={}&response_type={}&scope={}&state={}#wechat_redirect";url = Util.format(path, Constant.DEFAULT_APP_ID, redirect_uri, response_type, scope_, stateP);}try {resp.sendRedirect(url);} catch (IOException e) {LogCore.BASE.error("shouquan,scope={},", scope_, e);}}
前端代码;
window.onload = function() {var isappinstalled = s.getQuery("isappinstalled");var openid = s.getQuery("openid");var srcopenid = s.getQuery("srcopenid");//index.html?openid=XX&installedapp=0,说明是别人分享过来的,不过这时候仍可能之前保存有openidif(isappinstalled){if(localStorage.opid){srcopenid = openid;openid = localStorage.opid;window.history.replaceState({},0,'http://service.gaotianyue.com/moon/index.html?openid='+openid);}else{window.location = "http://service.gaotianyue.com/moon/signon?openid=" + openid;return;}}if(!openid){//尝试从本地缓存中获取if(localStorage.opid){openid = localStorage.opid;window.history.replaceState({},0,'http://service.gaotianyue.com/moon/index.html?openid='+openid);}else{window.location = 'http://service.gaotianyue.com/moon/signon';return;}}if (openid == srcopenid) {srcopenid = null;};
}
js控制URL地址的改变,以微信服务号的授权获取用户的昵称和头像为例相关推荐
- 微信公众号网页授权获取用户信息的流程
官网文档 网页授权流程分为四步: 引导用户进入授权页面同意授权,获取code 通过 code 换取网页授权access_token(与基础支持中的access_token不同)(我的需求只需要到第二部 ...
- 微信授权地理位置php,微信公众号第三方授权获取用户的的地理位置--坑
首先注册公众号,配置好 URL js URl ,这个就不多介绍了 第一步,直接 在菜单里 同意授权,获取code 这是第一个坑 ,记住,一定要用 urlEncode 对你的 重定向 URL 进行处 ...
- 微信公众号第三方授权获取用户的的地理位置--坑
首先注册公众号,配置好 URL js URl ,这个就不多介绍了 第一步,直接 在菜单里 同意授权,获取code 这是第一个坑 ,记住,一定要用 urlEncode 对你的 重定向 URL 进行处理 ...
- 微信服务号开发时获取授权遇到的问题
1.问题 (遇到的问题)微信服务号开发时获取授权遇到的问题 公众平台返回原始数据为: 错误代码-40164,错误信息-invalid ip, not in whitelist hint: [59FKq ...
- php微信授权没有code返回,解决关于微信公众号网页授权获取code参数的问题
解决关于微信公众号网页授权获取code参数的问题 发布时间:2018-07-24 23:21, 浏览次数:3327 , 标签: code * 在微信网页授权过程中,需要获取code参数,因为我用的是公 ...
- 微信公众号中 JavaScript 获取用户周边的标志性建筑列表
微信公众号中 JavaScript 获取用户周边的标志性建筑列表 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致& ...
- 微信公众号H5页面获取用户昵称头像等信息(Java)
H5页面获取微信用户信息操作流程 (一)获取微信权限,由微信用户确认 (二)获取相应的ACCESS_TOKEN和OPENID信息 (三)根据ACCESS_TOKEN和OPENID信息获取相应的用户信息 ...
- c#实现微信公众号开发--服务号通过oauth2获取用户信息
2018年春节策划了一个"带现金红包的贺年卡"微信号推广活动,先说下效果:2个小时实现新增关注用户4万多户,活动页面PV达到16.8万,后因红包预算费用原因结束活动. 实现原理:每 ...
- 微信开发之网页授权获取用户基本信息
微信官方文档:网页授权获取用户基本信息 具体而言,网页授权流程分为四步: 1.引导用户进入授权页面同意授权,获取code https://open.weixin.qq.com/connect/oaut ...
最新文章
- checkboxlist 数据库连接代码
- [Leetcode]50. Pow(x, n)
- 2015-07-22 JQuery 第二课(JQ元素获取,添加,删除,判断,遍历,取值,样式设置,改变对象,切换)...
- T-SQL查询——数据集之间的运算
- ins40401 oracle,安装orace grid infrastructure 提示[INS-40404]问题
- python消息推送_Python阿里云消息推送调用API
- Spring+Quartz实现定时执行任务的配置
- Zimbra开发接口文档API下载地址
- citra 图形设置_TinkerTool System 6 for Mac(系统深度设置维护工具)
- async和await用法
- Java编程:树(基础部分)
- andorid自定义ViewPager之——子ViewPager滑到边缘后直接滑动父ViewPager
- neo4j---学习笔记
- 业务模式制胜,BLM战略规划七步法
- 计算机Auto服务错误1053,Win7电脑宽带连接错误1053的原因和解决方案
- 《老路用得上的商学课》56-60学习笔记
- python视频分段_Python玩转视频处理(四):视频按场景进行分割
- parrot linux iso下载,Parrot Security OS 4.0发布下载,面向安全的操作系统
- Oracle 10g 版本10.2.0.1.0升级到Oracle 10g 10.2.0.3.0过程
- vue展示日历 考勤展示_基于element-ui的日历显示当月考勤情况