Web项目开发实践,Cookie与Session机制(二)

2022-02-15 15:47:09 浏览数 (1)

5.1.3 Cookie的不可跨域名性

很多网站都会使用Cookie。例如,Google会向客户端颁发Cookie,Baidu也会向客户端颁发Cookie。那浏览器访问Google会不会也携带上Baidu颁发的Cookie呢?或者Google能不能修改Baidu颁发的Cookie呢?

答案是否定的。Cookie具有不可跨域名性。根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。

Cookie在客户端是由浏览器来管理的。浏览器能够保证Google只会操作Google的Cookie而不会操作Baidu的Cookie,从而保证用户的隐私安全。浏览器判断一个网站是否能操作另一个网站Cookie的依据是域名。Google与Baidu的域名不一样,因此Google不能操作Baidu的Cookie。

需要注意的是,虽然网站images.google.com与网站www.google.com同属于Google,但是域名不一样,二者同样不能互相操作彼此的Cookie。

%注意:用户登录网站www.google.com之后会发现访问images.google.com时登录信息仍然有效,而普通的Cookie是做不到的。这是因为Google做了特殊处理。本章后面也会对Cookie做类似的处理。

5.1.4 Unicode编码:保存中文

中文与英文字符不同,中文属于Unicode字符,在内存中占4个字符,而英文属于ASCII字符,内存中只占2个字节。Cookie中使用Unicode字符时需要对Unicode字符进行编码,否则会乱码。编码可以使用java.net.URLEncoder类的encode(String str, String encoding)方法,解码使用java.net.URLDecoder类的decode(String str,String encoding)方法,例如:

代码语言:javascript复制
代码5.3  encoding.jsp
<%@ page language="java"pageEncoding="UTF-8" %>
<jsp:directive.page import="java.net.URLEncoder"/>
<jsp:directive.page import="java.net.URLDecoder"/>
<%
    // 使用中文的 Cookie. name 与 value 都使用 UTF-8 编码
    Cookie cookie = new Cookie(
        URLEncoder.encode("姓名", "UTF-8"),
        URLEncoder.encode("刘京华", "UTF-8"));
    response.addCookie(cookie); // 发送到客户端
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01Transitional//EN">
<html>
<head>
<title>Cookie Encoding</title>
</head>
<body>
<%
    if(request.getCookies() != null){
        for(Cookie cc :request.getCookies()){      // 遍历所有的Cookie
            String cookieName= URLDecoder.decode(cc.getName(), "UTF-8");
            StringcookieValue = URLDecoder.decode(cc.getValue(), "UTF-8");
           out.println(cookieName   "="   cookieValue   ";<br/>");
        }
    }
    else{
        out.println("Cookie 已经写入客户端. 请刷新页面. ");
    }
%>
</body>
</html>

程序使用UTF-8编码了Cookie内容,然后再使用UTF-8解码Cookie并显示出来。程序运行效果如图5.3所示。

图5.3 Cookie的UTF-8编码

%提示:Cookie中保存中文只能编码。一般使用UTF-8编码即可。不推荐使用GBK等中文编码,因为浏览器不一定支持,而且JavaScript也不支持GBK编码。

5.1.5 BASE64编码:保存二进制图片

Cookie不仅可以使用ASCII字符与Unicode字符,还可以使用二进制数据。例如在Cookie中使用数字证书,提供安全度。使用二进制数据时也需要进行编码。下面的例子使用BASE64编码在Cookie中保存二进制文件。源代码如下:

代码语言:javascript复制
代码5.4  base64.jsp
<%@ page language="java"pageEncoding="UTF-8" %>
<jsp:directive.pageimport="sun.misc.BASE64Encoder"/>
<jsp:directive.pageimport="java.io.InputStream"/>
<jsp:directive.pageimport="java.io.File"/>
<%
    File file = newFile(this.getServletContext().getRealPath("cookie. 
    gif"));
    byte[] binary = newbyte[(int)file.length()];       // 二进制数组
    // 从图片文件读取二进制数据.
    InputStream ins =this.getServletContext().getResourceAsStream 
    (file.getName());
    ins.read(binary);
    ins.close();   
    String content =BASE64Encoder.class.newInstance().encode(binary); 
    // BASE64 编码
    Cookie cookie = newCookie("file", content);
                                              // 包含二进制数据的 Cookie
    response.addCookie(cookie);                // 将 Cookie 发送到客户端
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01Transitional//EN">
<html>
<head>
<title>Cookie Encoding</title>
</head>
<body>
从 Cookie 中获取到的二进制图片:<imgsrc="base64_decode.jsp" /> <br/>
<textarea id='cookieArea' style='width:100%;height:200px; '></textarea>
<scripttype="text/javascript">cookieArea.value=document.cookie;</script>
</body>
</html>

程序使用的二进制数据来自根目录下的cookie.gif文件。程序先将二进制数据写进客户端Cookie中,然后又将Cookie中的二进制数据还原并显示。输入框中用JavaScript程序显示了客户端Cookie的所有内容。

解码并显示图片的源代码如下:

代码语言:javascript复制
代码5.5 base64_decode.jsp
<%@ page language="java"pageEncoding="UTF-8" %>
<jsp:directive.page import="sun.misc.BASE64Decoder"/>
<jsp:directive.page trimDirectiveWhitespaces="true"/>
<%
    out.clear();                                  // 清除输出
    for(Cookie cookie : request.getCookies()){     // 遍历Cookie
       if(cookie.getName().equals("file")){       // 找到名为file的Cookie
            byte[] binary =
           BASE64Decoder.class.newInstance().decodeBuffer(cookie. 
           getValue().replace(" ", ""));   // 解码BASE64编码的二进制内容
           response.setHeader("Content-Type", "image/gif");
                                          // 设置内容类型为 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;
        }
    }
%>

程序运行效果如图5.4所示。选中的部分为二进制Cookie编码后的内容。输入框上方的小图标就是解密后Cookie显示的图片。

图5.4 Cookie中的二进制数据

%注意:本程序仅用于展示Cookie中可以存储二进制内容,并不实用。由于浏览器每次请求服务器都会携带Cookie,因此Cookie内容不宜过多,否则影响速度。Cookie的内容应该少而精。

0 人点赞