记一次iphone 微信内置浏览器跨域无法获取cookie问题的解决方法
2016-05-15 15:24
871 查看
前两天刚完成了一个账号打通的需求,两个站点不是一个域名(暂且用A.com和B.com代替两个站点域名),因此采用了jsonp跨域请求的方式来获取不同域名下的cookie值。jsonp跨域请求在这里就不赘述了,百度一搜一大把。
项目上线两天,被公司一同事发现一个Bug,就是苹果手机的微信账号登出后,再登录微信。在A站点进行登录后,会反复跳转登录页面。通过本地的fiddler进行抓取跳转路径后发现,A站点登录后,通过jsonp请求去B站点下cookie中获取用户的登录状态是未登录。但是我们在B站点的cookie中却有用户的登录信息。(在这里要说明一下,A站点的登录页面集成的是B站的登录控件,因此虽然是在A站点登录,但是用户的登录信息却是写在B站点域名下的cookie中)这样就有问题了,为了检验这个问题是代码逻辑问题还是个例?我们用苹果手机和安卓手机分别对安装的浏览器优先进行了测试,发现A站点登陆后,可以通过jsonp请求拿到B站点cookie中的用户登陆状态。因此可以判定应该不是代码逻辑的问题。
然后进一步验证是不是微信内置的浏览器的问题,我们发现在未退出微信账号的情况下,苹果手机和安卓手机均不会出现上述问题。然后分别退出微信账号,再登录。安卓手机不会出现无法登陆成功的情况,可以直接进行后续的操作。所以确定这种问题只有在苹果手机的微信端入口有这种问题。
我们查资料的得知,安卓版微信内置的是QQ浏览器的X5内核,而苹果不允许其他浏览器内核,好像用的是苹果的内核。(但我们不确定是不是这个内核原因造成的。)微信登出后,此时会将所有的cookie信息清空。
我们通过本地的fiddler拦截请求发现,微信IOS客户端,cookie清空后,发起jsonp跨越请求,无法写入cookie,但是我们用微信浏览器访问一下B站点的主页后(这个过程会在B站点cookie中写部分cookie值),再在A站点登录后,就可以通过jsonp请求获取B站点域名下cookie中的用户登录状态了。
此时我们初步认定IOS系统的微信清空cookie后,不能直接用jsonp跨域写cookie,我们查找资料发现别人也遇到过类似的情况,但是没有很好的解决办法。
但是通过前面的测试方法,发现只要B站点域名下有cookie值(随意的cookie,只要有内容就行),我们这时候在A站点登录,然后通过jsonp请求B站点域名下的cookie值,就可以获取到用户的登录状态(cookie值完全为空则写不进去cookie值)。我们就采取了一个折中的解决办法,在页面上判断只要是IOS微信客户端访问页面,我们就让其增加一次跳转(目前只有苹果手机微信客户端有该问题),让其先访问一个和B站点域名一样的一个中间站点,随意写一些cookie值,然后再重定向到之前实际要访问的页面,这样就在A站点进行登陆后,通过jsonp请求就可以获取到B站点域名下cookie中的用户登录态了。
前端代码如下:
后端代码如下:
重定向回到投递页面时,在执行jsonp请求,即可正常进行后续的流程,前端发jsonp代码如下:
以上其实没有真正解决了IOS微信内置浏览器不能通过Jsonp写cookie的问题,只是用取巧的方式解决了上面出现的问题。在此写下这篇文章记录一下解决问题的方法。希望以后有别人遇到类似的问题,可以提供一点参考的思路。
如果有人解决了上面类似的问题,欢迎留言,一起探讨一下。
项目上线两天,被公司一同事发现一个Bug,就是苹果手机的微信账号登出后,再登录微信。在A站点进行登录后,会反复跳转登录页面。通过本地的fiddler进行抓取跳转路径后发现,A站点登录后,通过jsonp请求去B站点下cookie中获取用户的登录状态是未登录。但是我们在B站点的cookie中却有用户的登录信息。(在这里要说明一下,A站点的登录页面集成的是B站的登录控件,因此虽然是在A站点登录,但是用户的登录信息却是写在B站点域名下的cookie中)这样就有问题了,为了检验这个问题是代码逻辑问题还是个例?我们用苹果手机和安卓手机分别对安装的浏览器优先进行了测试,发现A站点登陆后,可以通过jsonp请求拿到B站点cookie中的用户登陆状态。因此可以判定应该不是代码逻辑的问题。
然后进一步验证是不是微信内置的浏览器的问题,我们发现在未退出微信账号的情况下,苹果手机和安卓手机均不会出现上述问题。然后分别退出微信账号,再登录。安卓手机不会出现无法登陆成功的情况,可以直接进行后续的操作。所以确定这种问题只有在苹果手机的微信端入口有这种问题。
我们查资料的得知,安卓版微信内置的是QQ浏览器的X5内核,而苹果不允许其他浏览器内核,好像用的是苹果的内核。(但我们不确定是不是这个内核原因造成的。)微信登出后,此时会将所有的cookie信息清空。
我们通过本地的fiddler拦截请求发现,微信IOS客户端,cookie清空后,发起jsonp跨越请求,无法写入cookie,但是我们用微信浏览器访问一下B站点的主页后(这个过程会在B站点cookie中写部分cookie值),再在A站点登录后,就可以通过jsonp请求获取B站点域名下cookie中的用户登录状态了。
此时我们初步认定IOS系统的微信清空cookie后,不能直接用jsonp跨域写cookie,我们查找资料发现别人也遇到过类似的情况,但是没有很好的解决办法。
但是通过前面的测试方法,发现只要B站点域名下有cookie值(随意的cookie,只要有内容就行),我们这时候在A站点登录,然后通过jsonp请求B站点域名下的cookie值,就可以获取到用户的登录状态(cookie值完全为空则写不进去cookie值)。我们就采取了一个折中的解决办法,在页面上判断只要是IOS微信客户端访问页面,我们就让其增加一次跳转(目前只有苹果手机微信客户端有该问题),让其先访问一个和B站点域名一样的一个中间站点,随意写一些cookie值,然后再重定向到之前实际要访问的页面,这样就在A站点进行登陆后,通过jsonp请求就可以获取到B站点域名下cookie中的用户登录态了。
前端代码如下:
function GetQueryString(name) { var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&|$)"); var r = window.location.search.substr(1).match(reg); if(r!=null)return unescape(r[2]); return ""; } $(function(){ var isJump = GetQueryString("isJump"); console.debug(isJump); if (typeof(isJump) == "undefined" || isJump == ""){ //先跳一个中间站点,进行写cookie动作 location.href="http://www.jump.B.com/testurl?infoid=" + __Global.infoid; } });
后端代码如下:
@Path("/testurl") public ActionResult redirecturl(){ //写入cookie long infoid = ParamUtil.getLong(beat.getRequest(), "infoid", 0L); HttpServletResponse response = beat.getResponse(); Cookie c = new Cookie("isJump", "from"); c.setDomain(".B.com"); c.setPath("/"); c.setMaxAge(20000); response.addCookie(c); //重定向 String url = "http://A.com/detail/"+infoid+"/?isJump=1"; System.out.println("url="+url); return ActionResult.redirect(url); }
重定向回到投递页面时,在执行jsonp请求,即可正常进行后续的流程,前端发jsonp代码如下:
//在线报名回调函数 function onlineApply(){ //jsonp远程请求加密字符串 $.ajax({ url: 'http://www.jump.B.com/get/userid', type: 'get', dataType: 'jsonp', success: function(res){ var par = {}; var success = res.success; par.infoid = __Global.infoid; par.baseStr = res.data; //如果用户登录 if(success){ //投递操作 applyHandle(par); }else{ location.href = domain+"/login?cityid="+__Global.cityid+"&cateid="+__Global.cateid+"&infoid="+__Global.infoid; } }, error: function(){ $(".scheme_fail .dialog_header").html("网络错误"); popShow(".scheme_fail"); } }); }
以上其实没有真正解决了IOS微信内置浏览器不能通过Jsonp写cookie的问题,只是用取巧的方式解决了上面出现的问题。在此写下这篇文章记录一下解决问题的方法。希望以后有别人遇到类似的问题,可以提供一点参考的思路。
如果有人解决了上面类似的问题,欢迎留言,一起探讨一下。
相关文章推荐
- 微信局域网测试环境搭建方法
- 微信扫码支付(模式一)
- 玩转微信支付全过程
- [置顶] Android:NineGridLayout — 仿微信朋友圈和QQ空间的九宫格图片展示自定义控件
- iBotCloud-小i机器人在微信公众号中实现智能回答
- 微信分享闪退问题分析及解决
- 微信JS SDK PHP Demo
- 微信开发——前期配置
- 用Node.js开发微信公众号
- 微信html5开发平台
- 微信公众号
- 微信群九大规律 - 47万微信群和2亿微信用户背后的故事
- 阅读量上不去?你的公众号是不是犯了这几个问题
- iOS 分享到qq好友,qq空间,微信好友,微信朋友圈,新浪微博
- 微信课堂的初步确立
- 微信网页中长按二维码图片能弹出菜单是怎么实现的?
- 微信中关闭网页输入内容时的安全提示 [干掉 “防盗号或诈骗,请不要输入QQ密码”]
- 微信WeixinJSBridge API
- 微信内置浏览器的JsAPI(WeixinJSBridge续)[转载]
- 传说中的WeixinJSBridge和微信rest接口