1、从存储方式上比较
Cookie中只能保存ASCII字符串,如果需要存取Unicode字符或是二进制数据,需要进行UTF-8、GBK或者BASE64等方式编码。Cookie中也不能直接存取Java对象,若要存取稍微复杂的数据,Cookie是比较困难的
而Session中可以存取任何类型的数据,包括但不限于String、Integer、List、Map等,Session中也可以直接保存Java Bean乃至任何Java类,使用起来非常方便,可以吧Session看做是一个Java容器类
base64转码实例:
<%@ page language="java" pageEncoding="UTF-8" %>
<%
//图片放于根目录下
File file = new File(this.getServletContext().getRealPath("cookie.gif"));
// 二进制数组
byte[] binary = new byte[(int)file.length()];
// 从图片文件读取二进制数据.
InputStream ins = this.getServletContext().getResourceAsStream(file.getName());
ins.read(binary);
ins.close();
// BASE64 编码
String content = BASE64Encoder.class.newInstance().encode(binary);
// 包含二进制数据的 Cookie
Cookie cookie = new Cookie("file", content);
// 将 Cookie 发送到客户端
response.addCookie(cookie);
%>
Cookie Encoding
从 Cookie 中获取到的二进制图片:
<script type="text/javascript">cookieArea.value=document.cookie;</script>
<%@ page language="java" pageEncoding="UTF-8" %>
<%
// 清除输出
out.clear();
for(Cookie cookie : request.getCookies()){
if(cookie.getName().equals("file")){
// 从 Cookie 中取二进制数据
byte[] binary = BASE64Decoder.class.newInstance().decodeBuffer(cookie.getValue().replace(" ", ""));
// 设置内容类型为 gif 图片
response.setHeader("Content-Type", "image/gif");
response.setHeader("Content-Disposition", "inline;filename=cookie.gif");
response.setHeader("Connection", "close");
// 设置长度
response.setContentLength(binary.length);
// 输出到客户端
response.getOutputStream().write(binary);
response.getOutputStream().flush();
response.getOutputStream().close();
return;
}
}
%>
utf-8转码实例
<%@ page language="java" pageEncoding="UTF-8" %>
<%
// 使用中文的 Cookie. name 与 value 都使用 UTF-8 编码.
Cookie cookie = new Cookie(
URLEncoder.encode("姓名", "UTF-8"),
URLEncoder.encode("我", "UTF-8"));
// 发送到客户端
response.addCookie(cookie);
%>
Cookie Encoding
<%
if(request.getCookies() != null){
for(Cookie cc : request.getCookies()){
String cookieName = URLDecoder.decode(cc.getName(), "UTF-8");
String cookieValue = URLDecoder.decode(cc.getValue(), "UTF-8");
out.println(cookieName + "=");
out.println(cookieValue + ";
");
}
}
else{
out.println("Cookie 已经写入客户端. 请刷新页面. ");
}
%>
2、从隐私安全上比较
Cookie存储在客户端浏览器中,对客户端是可见的,客户端的一些程序可能窥探、复制甚至修改Cookie中的内容,而Session在存储在服务器上,对客户端是透明的,不存在敏感信息泄露的危险。
如果选用Cookie,比较好的方法是敏感信息如账号密码等尽量不要写到Cookie中,最好是想谷歌百度那样讲敏感信息加密,提交到服务器后解密,保证Cookie中的信息只有自己能看得懂,而如果选择Session就省事多了,反正是放在服务器上,Session里任何隐私都可以
3、从有效期上比较
Cookie的maxAge属性支持永久登录的的效果,只需要把maxAge属性设置为一个很大的数字或是Integer..MAX_VALUE就可以了
使用Session理论也可以达到这种效果,只需要调用方法setMaxInactuveInterval(integer.MAX_VALUE)。但是由于Session依赖于名为JSESSIONID的Cookie,而该Cookie的maxAge属性默认为-1,所以只要关闭了浏览器该Session就会失效,因此Session不能实现永久登录的功能,使用URL地址重写也不行。
4、从对服务器的负担上比较
由于Session是存储在服务端的,因此对于并发访问量极高的网站(如百度,谷歌),是不太可能使用Session来跟踪客户对话的
而Cookie由于是存储在客户端的,不占用服务器资源,所以没有这方面的担忧
5、从浏览器支持上比较
Cookie需要客户端浏览器的支持,如果客户端禁用了Cookie,或者支持Cookie,则会话跟踪就会失败。对于WAP(不支持Cookie),常规的COokie则派不上用场,这时就需要使用Session以及URL重写,需要注意的是所有用到Session程序的URL重写都要使用response.encodeURL(String URL)或者response.encodeRedirectURL(String URL),否则导致Session会话失败
如果客户端支持Cookie,则Cookie可以设置为本浏览器窗口及其子窗口有效(maxAge=-1),也可以设置为所有浏览器窗口有效(maxAge=Integer.MAX_VALUE),而Session只能在本浏览器窗口及其子窗口有效。如果俩个浏览器窗口互不相干,则将使用到俩个不同的Session。
此处附上URL地址重写(代码可能有些许错误);
原理:将该用户的Session的id信息重写到URL地址中,
服务器能够解析重写后的URL获取Session的id,这样即使客户端不支持Cookie,也可以使用Session记录用户状态,例如:
">HomePage
该方法会自动判断客户端是否支持Cookie,如果客户端支持Cookie,则会将URL原封不动地输出来,否则将用户Session的id重写到URL中,重写后的输出可能是这样的:
homePage
即添加了字符串";jsessionid=XXXX"。其中XXXX是Session的id
6、从跨域名上比较
Cookie支持跨域名访问,只需要将domain属性设置为相应域名后缀(如:.baidu.com,注意此处是以“.”开头的),则以该域名为后缀的所有网站都可以访问该Cookie,而Session则不支持。