浏览器中,Cookie分为两类,Session Cookie和持久化Cookie。
如果在创建Cookie的时候,只设置了key和value,则是Session Cookie;如果 创建 Cookie的时候,不仅设置了key/value,同时设置了Cookie的生存时间,则这样的Cookie是持久化Cookie。
以下是java中创建Session Cookie和持久化Cookie的方式:
//Session Cookie Cookie sessionCookie = new Cookie("s", "session"); //持久化Cookie Cookie persCookie = new Cookie("p","persistance"); persCookie.setMaxAge(100000);
在ie浏览器中,通过诸如iframe、script、link访问资源或者页面的时候,默认是只带Session Cookie的,持久化的Cookie是不携带过去的。
现在有一个页面main.jsp,上边有一个访问了别的域下的javascript文件的<script>标签和一个访问了别的域名的iframe:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=GB18030"> <meta http-equiv="pragma" content="no-cache"/> <script type="text/javascript" src="http://10.13.103.37:8080/CookieTest/helloworld.js"></script> <title>main</title> </head> <body> main <br><br> <hr> <iframe src="http://10.13.103.37:8080/CookieTest/csrf.jsp" id="abc" width="800" height="600"></iframe> </body> </html>
另外有一个servlet是用来设置cookie的,设置了一个session cookie一个持久化cookie:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //Session Cookie Cookie sessionCookie = new Cookie("s", "session"); //持久化Cookie Cookie persCookie = new Cookie("p","persistance"); persCookie.setMaxAge(100000); response.addCookie(sessionCookie); response.addCookie(persCookie); getServletConfig().getServletContext().getRequestDispatcher("/csrf.jsp").forward(request, response); }
先调用这个Servlet给http://10.13.103.37:8080/这个域下设置Cookie:
然后请求main.jsp,会发现script和iframe中的请求都只带了Session Cookie:
但是如果此前一次请求的响应有P3P头返回,则可以跨域读写Cookie的,包括持久化的Cookie。
设置P3P头:
response.addHeader("P3P", "CP=CURa ADMa DEVa PSAo PSDo OUR BUS NUI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR");
访问有设置P3P头的Servlet设置cookie:
设置后跨域请求js和iframe请求页面:
这些东西什么地方会用到呢?
在淘宝系统中,淘宝和天猫都是独立的域名,付款是支付宝的付款,也是单独的域名,三个站点之间的交互是很频繁的,也会存在跨域访问的问题,跨域认证又需要单点登录的时候,cookie的携带就很重要了。而且在这个过程中也出现过不少问题的,后续有空继续吐槽。