比如说a.com和b.com两个不同的域,我在a.com中登录后,在b.com中就可以显示登录状态。
一、首先是在a.com中登录时,保存cookie,具体就不说了,先只把保存和读取cookie的工具类写下(这里要特别注意在保存cookie前对P3P头的设置,在后面会有具体说明):
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import sun.misc.BASE64Encoder;
import cn.org.csip.jzzhaopin.model.Companyinfo;
import cn.org.csip.jzzhaopin.model.User;
public class MyCookieUtil {
// 保存cookie时的cookieName
private final static String cookieDomainName = Constants.COOKIE_NAME;
// 加密cookie时的网站自定码
private final static String webKey = "csip";
// 设置cookie有效期是两小时,根据需要自定义
private final static long cookieMaxAge = 60*60*2 ;
// 保存Cookie到客户端--------------------------------------------------------------------------------------------------------
// 传递进来的user对象中封装了在登陆时填写的用户名与密码
public static void saveCookie(User user, HttpServletResponse response) {
// cookie的有效期
long validTime = System.currentTimeMillis() + (cookieMaxAge * 1000);
// MD5加密用户详细信息
String cookieValueWithMd5 = md5(user.getPwd());
// 将要被保存的完整的Cookie值
String cookieValue = user.getId()+":"+user.getUsercode() + ":" + cookieValueWithMd5
+ ":" + validTime + ":" + webKey+":"+"1";
//在保存cookie前要设置P3P头,主要是在跨域取cookie的时候,防止IE浏览器的阻止cookie的读取
response.setHeader("P3P","CP=\"CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR\"");
// 开始保存Cookie
Cookie cookie;
try {
cookie = new Cookie(cookieDomainName, URLEncoder.encode(cookieValue, "utf-8"));
// 存两小时(这个值应该大于或等于validTime)
cookie.setMaxAge(2*60*60);
// cookie有效路径是网站根目录
cookie.setPath("/");
//设置跨域cookie
//cookie.setDomain(".jzzhaopin.org.cn");
// 向客户端写入
response.addCookie(cookie);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
//取cookie
public String getCookies(String cookiename,HttpServletRequest request){
Cookie[] cookie = request.getCookies();
String cookievalue=null;
if(cookie!=null){
for(int i=0;i<cookie.length;i++){
if(cookie[i].getName().equals(cookiename))
{
try {
cookievalue=URLDecoder.decode(cookie[i].getValue(), "utf-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
break;
}
}
}
return cookievalue;
}
public Cookie clearCookie(String cookiename,HttpServletRequest request,HttpServletResponse response){
Cookie[] cookie = request.getCookies();
if(cookie!=null){
for(int i=0;i<cookie.length;i++){
if(cookie[i].getName().equals(cookiename)){
cookie[i].setMaxAge(0);
cookie[i].setPath("/");
response.addCookie(cookie[i]);
return cookie[i];
}
}
}
return null;
}
public static String md5(String message) {
try {
MessageDigest md = MessageDigest.getInstance("md5");
byte[] result = md.digest(message.getBytes());
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(result);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
}
二、在b.com中读取cookie,我是通过jquery的getJSON方法跨域访问的cookie的。要页面加载时调用getJSON方法,去跨域读取a.com中的cookie。主要代码如下:
<script >
$(function(){
$.getJSON('http://a.com/index/getCookieName.do?callback=?'+'&time='+new Date(),
function(data){
if(data[0]=="false"){
document.getElementById('welcome').innerHTML='';
}else if(data[0]=="cn.org.csip"){
document.getElementById('unlogin_l').style.display='none';
document.getElementById('unlogin_r').style.display='none';
document.getElementById('login_l').style.display='block';
if(data[data.length-1]=='1'){
datavalue='个人';
document.getElementById('welcome').innerHTML='欢迎您:'+data[2]+','
+'<a href="http://119.254.229.94:8980/jzzhaopin/ucenter/personalInfo.do">[进入'+datavalue+'中心]</a><a href="http://localhost:8080/jzzhaopin/login/logout.do">[注销]</a>';
}
if(data[data.length-1]=='2'){
datavalue='单位';
document.getElementById('welcome').innerHTML='欢迎您:'+data[2]+','
+'<a href="http://119.254.229.94:8980/jzzhaopin/hr/companyinfo.do">[进入'+datavalue+'中心]</a><a href="http://localhost:8080/jzzhaopin/login/logout.do">[注销]</a>';
}
}
});
});
</script>
其中,异步调用的aciton的代码为:
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import net.sf.json.JSONArray;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import cn.org.csip.common.web.BaseAction;
import cn.org.csip.util.Constants;
import cn.org.csip.util.MyCookieUtil;
public class GetCookieNameAction extends BaseAction {
@Override
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
response.setContentType("text/html;charset=utf-8");//此处必须设置该编码,否则中文到页面会出现乱码
response.setHeader("P3P", "CP=\"IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA\"");
//response.addHeader("P3P", "CP=\"IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA\"");
String callback = request.getParameter("callback"); //获取回调函数的名字,此处一定不能少
PrintWriter out=response.getWriter();
//1.得到用户带过来的cookie
MyCookieUtil myCookieUtil=new MyCookieUtil();
String cookievalue=myCookieUtil.getCookies(Constants.COOKIE_NAME, request);
if(cookievalue!=null){
cookievalue=Constants.COOKIE_NAME+":"+cookievalue;
String[] cookievalues=cookievalue.split("\\:");
JSONArray json = JSONArray.fromObject(cookievalues);
out.write(callback+"("+json.toString()+")");//此处注意返回的数据的格式,callback是一个函数,json.toString相当于是参数,所以要加个括号
//out.write(Constants.COOKIE_NAME+":"+cookievalues[1]+";"+cookievalues[cookievalues.length-1]);
}else{
out.write(callback+"([\"false\"])");//此处是自定义json格式的数据
}
return null;
}
}
需要注意的是:
用jquery的getJSON方法,事实上取得不是cookie,而是跨域取值。注意调的函数的json数据格式一定要严格按照action中写的那样,具体参看GetCookieNameAction.java;
url后面的callback是自定义的回调函数,后面的“?”就是一个具体的函数,只不过这里做了简化,可能是因为具体是什么函数无所谓,只要给个函数就行了。
IE浏览器,对cookie做了很严格的设置,即时按照上面的跨域方法,也是获取不到cookie的,解决方有两个:
一、更改本机的浏览器设置:更改隐私设置,级别调成最低即可;
二、在发送cookie的请求页面中(或者保存cookie的后台代码中)加入P3P头(只需要加入一次即可):针对java,在保存cookie之前,加上代码 response.setHeader("P3P","CP=\"CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR\"");
下面转载一篇关于P3P设置的文章,写的挺好,想具体了解下的可以看一下:http://blog.csdn.net/lovingprince/article/details/5984449