情景:公司的一個網站有一個模塊(測試模塊)需要單獨用另外的一個域名(www.xyz.com)去訪問,即網站需要用兩個不同的域名去訪問,如首頁(www.abc.com)和測試模塊(www.xyz.com)
這時候就涉及到session跨域問題,因為域名不是父子關系,所以必須要實現完全跨域,想到了以下三個解決辦法:
1.URL傳參:測試模塊訪問的時候,地址www.xyz.com后把主域名的session通過參數的形式傳遞過去,如:www.xyz.com;jsessionid=7D4DED1F2DB5BC53961EFED18BCE7E30
2.SSO單點登錄
3.利用jsonp的跨域特性,通過ajax進行session傳遞
第一種方案考慮URL傳參數不美觀以及URL需要分享給別人的時候就沒法獲取到session,所以放棄
第二種SSO單點登錄方案應該在三種方案中最優的,因為系統架構問題,所以也放棄
目前采用的是第三種方案:
1.把網站主域名的頭部和測試模塊的頭部分開,在測試模塊的頭部加入以下js代碼:
(使用測試模塊域名www.xyz.com進行網站訪問的時候,利用jsonp跨域特性去主域名www.abc.com獲取session信息,然后把session信息設置到測試模塊域名中)
var user = '${sessionScope.username}';//獲取session信息
//先跨域去取主域名登錄的session信息 $.getJSON("www.abc.com/user/getname?callback=?",function(data){ if(data != null && data != ""){ //把取到的session數據設置到當前域名的session信息中
$.getJSON("www.xyz.com/user/setname?data="+data+"&callback=?",function(data){ if((user == null || user == "") && data != null && data != ""){ window.location.reload();//需要重新加載一下當前頁面,不然頭部不會顯示session信息 } }); }else{
//退出登錄時清除session信息 if(user != null && user != ""){ $.getJSON("www.xyz.com/user/setname?data=&callback=?",function(data){
if(data != null && data != "" && data == 'ok'){
window.location.reload();
}
});
}
}
});
2.后台實現代碼:
@RequestMapping(value="getname") @ResponseBody public String getName(HttpServletRequest request,HttpServletResponse response){ //獲取回調函數名 String callback = request.getParameter("callback"); String callRes = ""; try {
String username = (String) request.getSession().getAttribute("username");
if(StringUtils.isBlank(username)){
return callback + "()";
}
callRes = callback + "(" + JsonUtils.toJsonString(username) + ")";
} catch (Exception e) { callRes = callback + "()"; logger.error(e); } return callRes; } @RequestMapping(value="setname") @ResponseBody public String setName(HttpServletRequest request,HttpServletResponse response){ String callRes = ""; //獲取回調函數名 String callback = request.getParameter("callback"); String data = request.getParameter("data"); if(StringUtils.isBlank(data)){ request.getSession().invalidate(); return callback + "("+JsonUtils.toJsonString("ok")+")"; }
try { request.getSession().setAttribute("username", data); callRes = callback + "("+JsonUtils.toJsonString("ok")+")"; } catch (Exception e) { callRes = callback + "()"; request.getSession().invalidate(); logger.error(e); } return callRes; }
獲取session數據時是否進行數據加密,這個根據自己的需要,最好是把數據加密
session已經實現了共享,這種方案的缺點就是訪問測試模塊的時候,需要和服務器交互很多次,性能上肯定不好
誰有更好的解決方案,請 不吝賜教,在此感謝!
