您的位置:首页 > 移动开发 > 微信开发

记一次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中的用户登录态了。

前端代码如下:

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的问题,只是用取巧的方式解决了上面出现的问题。在此写下这篇文章记录一下解决问题的方法。希望以后有别人遇到类似的问题,可以提供一点参考的思路。

如果有人解决了上面类似的问题,欢迎留言,一起探讨一下。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: