Cookie

1、会话

  • 会话 : 用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。

  • 会话要解决的问题 : 保存每个用户的数据. 因为HTTP协议是无状态的,所以需要在服务器端管理客户端的状态, 也就是会话状态

  • 保存会话数据的两种技术

    • Cookie : 程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了

    • Session : 服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务

2、什么是Cookie

Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。 客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以 此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。

Cookie对象使用key-value属性对的形式保存用户状态,一个Cookie对象保存一个属性对,一个request或者response同时使用多个Cookie。因为Cookie类位于包javax.servlet.http.*下面,所以JSP中不需要import该类。

3、Cookie的不可跨域名性

很多网站都会使用Cookie。例如,Google会向客户端颁发Cookie,Baidu也会向客户端颁发Cookie。那浏览器访问Google会不会也携带上Baidu颁发的Cookie呢?或者Google能不能修改Baidu颁发的Cookie呢? 
答案是否定的。Cookie具有不可跨域名性。根据Cookie规范,浏览器访问Google只会携带GoogleCookie,而不会携带BaiduCookieGoogle也只能操作GoogleCookie,而不能操作BaiduCookie 
Cookie在客户端是由浏览器来管理的。浏览器能够保证Google只会操作GoogleCookie而不会操作 BaiduCookie,从而保证用户的隐私安全。浏览器判断一个网站是否能操作另一个网站Cookie的依据是域名。Google与Baidu的域名 不一样,因此Google不能操作Baidu的Cookie。

正常情况下,同一个一级域名下的两个二级域名如www.helloweenvsfei.com和 images.helloweenvsfei.com也不能交互使用Cookie,因为二者的域名并不严格相同。如果想所有 helloweenvsfei.com名下的二级域名都可以使用该Cookie,需要设置Cookie的domain参数,例如:

Cookie cookie = new Cookie("time","20080808"); // 新建Cookie
cookie.setDomain(".helloweenvsfei.com");           // 设置域名
cookie.setPath("/");                              // 设置路径
cookie.setMaxAge(Integer.MAX_VALUE);               // 设置有效期
response.addCookie(cookie);                       // 输出到客户端

注意:domain参数必须以点(“.”)开始。另外,name相同但domain不同的两个Cookie是两个不同的Cookie。如果想要两个域名完全不同的网站共有Cookie,可以生成两个Cookie,domain属性分别为两个域名,输出到客户端。 

4、Cookie的路径。

domain属性决定运行访问Cookie的域名,而path属性决定允许访问Cookie的路径(ContextPath)。例如,如果只允许/sessionWeb/下的程序使用Cookie,可以这么写:

Cookie cookie = new Cookie("time","20080808");     // 新建Cookie
cookie.setPath("/session/");                          // 设置路径
response.addCookie(cookie);                           // 输出到客户端

设置为“/”时允许所有路径使用Cookie。path属性需要使用符号“/”结尾。name相同但domain相同的两个Cookie也是两个不同的Cookie。

注意:页面只能获取它属于的Path的Cookie。例如/session/test/a.jsp不能获取到路径为/session/abc/的Cookie。使用时一定要注意。

  • 默认情况下,生成的Cookie的path为对应的程序的路径

  • 例如 : 以下示例以IE浏览器为准

    • http://localhost:8080/Session/001 生成的Cookie对应的path为Cookie:alpha@localhost/Session

    • http://localhost:8080/Session/demo/002 生成的Cookie对应的path为Cookie:alpha@localhost/Session/demo

    • 由于第二个path包含第一个path,所以第二个Cookie会包含第一个Cookie的信息,但是第一个Cookie不会包含第二个Cookie的信息

  • 在开发中,尽量通过手动方式设置path : Cookie.setPath("/")

5、Cookie的安全属性

HTTP协议不仅是无状态的,而且是不安全的。使用HTTP协议的数据不经过任何加密就直接在网络上传播,有被截获的可 能。使用HTTP协议传输很机密的内容是一种隐患。如果不希望Cookie在HTTP等非安全协议中传输,可以设置Cookie的secure属性为 true。浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie。下面的代码设置secure属性为true:

Cookie cookie = new Cookie("time", "20080808"); // 新建Cookie
cookie.setSecure(true);                           // 设置安全属性
response.addCookie(cookie);                        // 输出到客户端

提示:secure属性并不能对Cookie内容加密,因而不能保证绝对的安全性。如果需要高安全性,需要在程序中对Cookie内容加密、解密,以防泄密。

6、JavaScript操作Cookie

Cookie是保存在浏览器端的,因此浏览器具有操作Cookie的先决条件。浏览器可以使用脚本程序如 JavaScript等操作Cookie。这里以JavaScript为例介绍常用的Cookie操作。例如下面的代码会输出本页面 所有的Cookie。

<script>document.write(document.cookie);</script>

由于JavaScript能够任意地读写Cookie,有些好事者便想使用JavaScript程序去窥探用户在其他网 站的Cookie。不过这是徒劳的,W3C组织早就意识到JavaScript对Cookie的读写所带来的安全隐患并加以防备了,W3C标准的浏览器会 阻止JavaScript读写任何不属于自己网站的Cookie。换句话说,A网站的JavaScript程序读写B网站的Cookie不会有任何结果。

中文与英文字符不同,中文属于Unicode字符,在内存中占4个字符,而英文属于ASCII字符,内存中只占2个字节。Cookie中使用Unicode字符时需要对Unicode字符进行编码,否则会乱码。 
提示:Cookie中保存中文只能编码。一般使用UTF-8编码即可。不推荐使用GBK等中文编码,因为浏览器不一定支持,而且JavaScript也不支持GBK编码.

 

7、Cookie的有效期

Cookie的maxAge决定着Cookie的有效期,单位为秒(Second)。Cookie中通过getMaxAge()方法与setMaxAge(int maxAge)方法来读写maxAge属性。 
如果maxAge属性为正数,则表示该Cookie会在maxAge秒之后自动失效。浏览器会将maxAge为正数的 Cookie持久化,即写到对应的Cookie文件中。无论客户关闭了浏览器还是电脑,只要还在maxAge秒之前,登录网站时该Cookie仍然有效。 下面代码中的Cookie信息将永远有效。

Cookie cookie = new Cookie("username","helloweenvsfei");   // 新建Cookie
cookie.setMaxAge(Integer.MAX_VALUE);           // 设置生命周期为MAX_VALUE
response.addCookie(cookie);                    // 输出到客户端

如果maxAge为负数,则表示该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效。maxAge为负数的 Cookie,为临时性Cookie,不会被持久化,不会被写到Cookie文件中。Cookie信息保存在浏览器内存中,因此关闭浏览器该Cookie 就消失了。Cookie默认的maxAge值为

–1。 
如果maxAge为0,则表示删除该Cookie。Cookie机制没有提供删除Cookie的方法,因此通过设置该Cookie即时失效实现删除Cookie的效果。失效的Cookie会被浏览器从Cookie文件或者内存中删除, 
例如:

Cookie cookie = new Cookie("username","helloweenvsfei");   // 新建Cookie
cookie.setMaxAge(0);                          // 设置生命周期为0,不能为负数
response.addCookie(cookie);                    // 必须执行这一句
//response对象提供的Cookie操作方法只有一个添加操作add(Cookie cookie)。

8、Cookie的API及持久Cookie的删除

  • 会话Cookie : Cookie信息默认是保存在浏览器的内存中的,这叫做会话Cookie.

  • 持久Cookie : 保存在本地磁盘上的Cookie

  • 设置持久Cookie : Cookie.setMaxAge(int expiry) 单位是秒</font>

  • 持久Cookie的删除 : Cookie.setMaxAge(0);调用该方法时,路径必须和生成Cookie时保持一致,否则不能删除

要想修改Cookie只能使用一个同名的Cookie来覆盖原来的Cookie,达到修改的目的。删除时只需要把maxAge修改为0即可。

注意:从客户端读取Cookie时,包括maxAge在内的其他属性都是不可读的,也不会被提交。浏览器提交Cookie时只会提交name与value属性。maxAge属性只被浏览器用来判断Cookie是否过期。

注意:修改、删除Cookie时,新建的CookievaluemaxAge之外的所有属性,例如namepathdomain等,都要与原Cookie完全一样。否则,浏览器将视为两个不同的Cookie不予覆盖,导致修改、删除失败。     

9、API :

  • request.getCookies() : 取出所有Cookie

  • new Cookie(String name, String value) : 创建一个Cookie

  • response.addCookie(Cookie cookie) : 添加Cookie到响应中

  • cookie.getName() : 获取Cookie中的Name

  • cookie.getValue() : 获取Cookie中的Value

10、Cookie案例:获取上次访问时间

protected void doGet(HttpServletRequest request,
		HttpServletResponse response) throws ServletException, IOException {
	// 设置字符编码
	response.setContentType("text/html;charset=UTF-8");
	// 从请求中获取Cookie
	Cookie[] cookies = request.getCookies();
	// 如果Cookie为空,说明用户是第一次访问
	if (cookies == null) {
		// 获取当前时间
		long currentTimeMillis = System.currentTimeMillis();
		// 创建Cookie
		Cookie cookie = new Cookie("last", currentTimeMillis + "");
		// 添加Cookie到响应中
		response.addCookie(cookie);
		response.getWriter().write("欢迎您第一次访问本站");
	} else {// 如果Cookie不为空,说明用户不是第一次访问
		// 遍历所有Cookie
		for (Cookie cookie : cookies) {
			// 获取Cookie的name
			String name = cookie.getName();
			// 查找name为last的Cookie
			if (name.equals("last")) {
				// 获取Cookie中的值
				String value = cookie.getValue();
				// 转换时间
				long lastTime = Long.valueOf(value);
				Date date = new Date(lastTime);
				SimpleDateFormat sdf = new SimpleDateFormat(
						"yyyy-MM-dd HH-mm-ss");
				String format = sdf.format(date);
				response.getWriter().write("您的上次访问时间是:" + format);
				// 重新为Cookie赋值,并写回客户端
				long currentTimeMillis = System.currentTimeMillis();
				cookie = new Cookie("last", currentTimeMillis + "");
				response.addCookie(cookie);
			}
		}
	}
}

 

 

转载于:https://my.oschina.net/px828261/blog/1538433

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值