js控制URL地址的改变,以微信服务号的授权获取用户的昵称和头像为例
2016-09-20 17:54
1316 查看
当遇到某个场景需改变当前的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
但是这个活动,有个进一步的需求,当你分享出去后,要知道是谁分享给你的。
经过测试,分享出去的链接,再次打开后,会有个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。这不影响我们的逻辑,而且也正好避免了用户用这种分享出去后暴露自己的信息的情况。
下面是示例代码。
服务器:
前端代码;
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");// 提前放在腾讯回调的参数,放的是发朋友圈者的openid LogCore.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,说明是别人分享过来的,不过这时候仍可能之前保存有openid if(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; }; }
相关文章推荐
- 基于Node.js微信授权获取用户信息
- 微信小程序获取用户openid,头像昵称信息,后台java代码
- Qrcode生成二维码链接地址,网页授权获取微信用户信息
- java 微信授权后获取微信用户信息昵称乱码问题 解决
- 微信通过网页获取用户头像与昵称等信息
- Java 微信登录授权后获取微信用户信息昵称乱码问题解决
- 【微信】未关注公众号授权获取基本信息(头像昵称等)
- 微信小程序获取用户头像和昵称
- 微信网页授权获取用户信息 返回{"errcode":40066,"errmsg":"invalid url hint: [FZbxRA0556sz12!]"}错误
- 微信网页授权获取头像昵称,不弹出授权页面
- 微信开发笔记:获取用户openid,以及用户头像昵称等信息
- 微信的接口网页授权获取用户基本信息不是只有认证服务号才有
- 微信开发公共服务平台开发(.Net) - 网页授权获取用户基本信息
- 分别嵌入 新浪微博、QQ、微信 做第三方授权登录 获取到头像 昵称等信息
- js获取URL地址某个参数数据
- 获取网页URL地址及参数等的两种方法(js和C#)
- js 获取URL地址
- js获取地址栏url以及获取url参数
- JS获取当前网址,JS获取当前域名URL ,JS获取网站完整路径页面地址
- js获取URL地址