当遇到某个场景需改变当前的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地址的改变,以微信服务号的授权获取用户的昵称和头像为例相关推荐

  1. 微信公众号网页授权获取用户信息的流程

    官网文档 网页授权流程分为四步: 引导用户进入授权页面同意授权,获取code 通过 code 换取网页授权access_token(与基础支持中的access_token不同)(我的需求只需要到第二部 ...

  2. 微信授权地理位置php,微信公众号第三方授权获取用户的的地理位置--坑

    首先注册公众号,配置好 URL js URl ,这个就不多介绍了 第一步,直接 在菜单里 同意授权,获取code 这是第一个坑 ,记住,一定要用  urlEncode 对你的 重定向 URL  进行处 ...

  3. 微信公众号第三方授权获取用户的的地理位置--坑

    首先注册公众号,配置好 URL js URl ,这个就不多介绍了 第一步,直接 在菜单里 同意授权,获取code 这是第一个坑 ,记住,一定要用 urlEncode 对你的 重定向 URL 进行处理 ...

  4. 微信服务号开发时获取授权遇到的问题

    1.问题 (遇到的问题)微信服务号开发时获取授权遇到的问题 公众平台返回原始数据为: 错误代码-40164,错误信息-invalid ip, not in whitelist hint: [59FKq ...

  5. php微信授权没有code返回,解决关于微信公众号网页授权获取code参数的问题

    解决关于微信公众号网页授权获取code参数的问题 发布时间:2018-07-24 23:21, 浏览次数:3327 , 标签: code * 在微信网页授权过程中,需要获取code参数,因为我用的是公 ...

  6. 微信公众号中 JavaScript 获取用户周边的标志性建筑列表

    微信公众号中 JavaScript 获取用户周边的标志性建筑列表 太阳火神的美丽人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致& ...

  7. 微信公众号H5页面获取用户昵称头像等信息(Java)

    H5页面获取微信用户信息操作流程 (一)获取微信权限,由微信用户确认 (二)获取相应的ACCESS_TOKEN和OPENID信息 (三)根据ACCESS_TOKEN和OPENID信息获取相应的用户信息 ...

  8. c#实现微信公众号开发--服务号通过oauth2获取用户信息

    2018年春节策划了一个"带现金红包的贺年卡"微信号推广活动,先说下效果:2个小时实现新增关注用户4万多户,活动页面PV达到16.8万,后因红包预算费用原因结束活动. 实现原理:每 ...

  9. 微信开发之网页授权获取用户基本信息

    微信官方文档:网页授权获取用户基本信息 具体而言,网页授权流程分为四步: 1.引导用户进入授权页面同意授权,获取code https://open.weixin.qq.com/connect/oaut ...

最新文章

  1. checkboxlist 数据库连接代码
  2. [Leetcode]50. Pow(x, n)
  3. 2015-07-22 JQuery 第二课(JQ元素获取,添加,删除,判断,遍历,取值,样式设置,改变对象,切换)...
  4. T-SQL查询——数据集之间的运算
  5. ins40401 oracle,安装orace grid infrastructure 提示[INS-40404]问题
  6. python消息推送_Python阿里云消息推送调用API
  7. Spring+Quartz实现定时执行任务的配置
  8. Zimbra开发接口文档API下载地址
  9. citra 图形设置_TinkerTool System 6 for Mac(系统深度设置维护工具)
  10. async和await用法
  11. Java编程:树(基础部分)
  12. andorid自定义ViewPager之——子ViewPager滑到边缘后直接滑动父ViewPager
  13. neo4j---学习笔记
  14. 业务模式制胜,BLM战略规划七步法
  15. 计算机Auto服务错误1053,Win7电脑宽带连接错误1053的原因和解决方案
  16. 《老路用得上的商学课》56-60学习笔记
  17. python视频分段_Python玩转视频处理(四):视频按场景进行分割
  18. parrot linux iso下载,Parrot Security OS 4.0发布下载,面向安全的操作系统
  19. Oracle 10g 版本10.2.0.1.0升级到Oracle 10g 10.2.0.3.0过程
  20. vue展示日历 考勤展示_基于element-ui的日历显示当月考勤情况

热门文章

  1. 饮食健康会促进心理健康
  2. python中咕噜咕噜的冒泡函数
  3. C语言字符串函数及如何实现这些函数
  4. Unity 3D专栏 U3D预制包,很好很强大 (二)
  5. DSP TMS320F280049之模拟比较器CMPSS(寄存器版)
  6. Qt电子白板 画板 画笔 毛笔 钢笔 蜡笔 2D/3D图形 音视频播放
  7. 工业机器人关节拆装流程_工业机器人关节空间的插值轨迹规划_凌家良
  8. Java 反射与内省
  9. 天美L2工作室 凉经
  10. 使用GitHub打造你的个人主页