浅谈 Cookie

浅谈 Cookie

1、什么是Cookie

Cookie 就是浏览器储存在用户电脑上的一小段文本文件。cookie是一个纯文本文件,不包含任何可执行代码。cookie是以 “key=value” 的形式保存。

2、cookie 的用途

因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现。在典型的网上购物场景中,用户浏览了几个页面,买了一盒饼干和两瓶饮料。最后结帐时,由于HTTP的无状态性,不通过额外的手段,服务器并不知道用户到底买了什么,所以Cookie就是用来绕开HTTP的无状态性的“额外手段”之一。服务器可以设置或读取Cookies中包含信息,借此维护用户跟服务器会话中的状态。

在刚才的购物场景中,当用户选购了第一项商品,服务器在向用户发送网页的同时,还发送了一段Cookie,记录着那项商品的信息。当用户访问另一个页面,浏览器会把Cookie发送给服务器,于是服务器知道他之前选购了什么。用户继续选购饮料,服务器就在原来那段Cookie里追加新的商品信息。结帐时,服务器读取发送来的Cookie就行了。

Cookie另一个典型的应用是当登录一个网站时,网站往往会请求用户输入用户名和密码,并且用户可以勾选“下次自动登录”。如果勾选了,那么下次访问同一网站时,用户会发现没输入用户名和密码就已经登录了。这正是因为前一次登录时,服务器发送了包含登录凭据(用户名加密码的某种加密形式)的Cookie到用户的硬盘上。第二次登录时,如果该Cookie尚未到期,浏览器会发送该Cookie,服务器验证凭据,于是不必输入用户名和密码就让用户登录了。

3、cookie 的属性

Name和Value

name和value 为cookie的名字和值,一般保存为 name=value;

Domain属性

Domain属性指定Cookie所在的域名。

Domain属性可以使多个web服务器共享cookie。默认为,设置该Cookie的当前页面的域名,必须是当前发送Cookie的域名的一部分,只有访问的域名匹配上Domain属性,Cookie才会发送到服务端。

Path属性

Path属性用来指定Cookie路径,必须是绝对路径(比如/),如果未指定,默认为请求该Cookie的网页路径。

在发送Cookie的时候,只有Domain匹配成功了,才会进行Path的匹配判断。只有Path属性和Domain 路径相匹配,Cookie才会发送。这里的匹配是从根路径开始逐个字符计算,只要匹配发送路径的一部分,就可以。

发生跨域xhr请求时,即使请求URL的域名和路径都满足 cookie 的 Domain和Path,默认情况下cookie也不会自动被添加到请求头部中。

Expires属性

Expires属性,用于指定Cookie过期时间。

Expires必须是 GMT 格式的时间(可以通过 new Date().toGMTString()或者 new Date().toUTCString() 来获得)。

new Date().toGMTString() 或者 new Date().toUTCString()

如expires=Sat, 08 Sep 2018 02:26:00 GMT表示cookie将在2018年9月8日2:26分之后失效。

对于失效的cookie浏览器会清空。如果没有设置该选项,这样的cookie称为会话cookie。它存在内存中,当会话结束,也就是浏览器关闭时,cookie消失。

失效日期是以浏览器运行的电脑上的系统时间为基准进行核实的。没有任何办法来来验证这个系统时间是否和服务器的时间同步,所以当服务器时间和浏览器所处系统时间存在差异时这样的设置会出现错误。

Size属性

浏览器对Cookie数量的限制,规定不一样。目前,Firefox是每个域名最多设置50个Cookie,而Safari和Chrome没有域名数量的限制。所有Cookie的累加长度限制为4KB。超过这个长度的Cookie,将被忽略,不会被设置。

HttpOnly属性

设置Cookie的时候,如果服务器加上了HttpOnly属性,则这个Cookie无法被JavaScript读取(即document.cookie不会返回这个Cookie的值),只用于向服务器发送。进行AJAX操作时,XMLHttpRequest对象也无法包括这个Cookie,主要是为了防止XSS攻击盗取Cookie。

当cookie带httpOnly选项时,客户端则无法通过js代码去访问(包括读取、修改、删除等)这个cookie。

在客户端是不能通过js代码去设置一个httpOnly类型的cookie的,这种类型的cookie只能通过服务端来设置。

Secure属性

不像其它选项,该选项只是一个标记而没有值。只有当一个请求通过 SSL 或 HTTPS 创建时,包含 secure 选项的 cookie 才能被发送至服务器。这种 cookie 的内容具有很高的价值,如果以纯文本形式传递很有可能被篡改,例如:

Set-Cookie: name=Nicholas; secure

事实上,机密且敏感的信息绝不应该在 cookie 中存储或传输,因为 cookie 的整个机制原本都是不安全的。默认情况下,在 HTTPS 链接上传输的 cookie 都会被自动添加上 secure 选项。

Cookie 的维护

cookie 有四个标识符:cookie 的 namedomainpathsecure 标记。要想改变这个 cookie 的值,需要发送另一个具有相同 cookie namedomainpathSet-Cookie 消息头

这将覆盖原来 cookie 的值。但是,修改 cookie 选项的任意一项都将创建一个完全不同的新 cookie

cookie 自动删除

cookie 会被浏览器自动删除,通常存在以下几种原因:

  • 会话 cooke (Session cookie) 在会话结束时(浏览器关闭)会被删除
  • 持久化 cookie(Persistent cookie)在到达失效日期时会被删除
  • 如果浏览器中的 cookie 数量达到限制,那么 cookie 会被删除以为新建的 cookie 创建空间

服务端设置cookie

Web 服务器通过发送一个称为 Set-Cookie 的 HTTP 消息头来创建一个 cookie,Set-Cookie消息头是一个字符串,其格式如下(中括号中的部分是可选的):

Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]

服务端可以设置cookie 的所有选项:expires、domain、path、secure、HttpOnly

通过 Set-Cookie 指定的可选项只会在浏览器端使用,而不会被发送至服务器端。发送至服务器的 cookie 的值与通过 Set-Cookie 指定的值完全一样,不会有进一步的解析或转码操作。如果请求中包含多个 cookie,它们将会被分号和空格分开,例如:

Cookie: value1; value2; name1=value1

服务器端框架通常包含解析 cookie 的方法,可以通过编程的方式获取 cookie 的值。

客户端设置cookie

cookie不像web Storage有setItem,getItem,removeItem,clear等方法,需要自己封装。简单地在浏览器的控制台里输入:

最简单的设置多个cookie的方法就是重复执行document.cookie = “key=name”:

document.cookie = "name=lynnshen";
document.cookie = "age=18";

注意:

当name、domain、path 这3个字段都相同的时候,cookie会被覆盖。

Java 中的 Cookie

获取所有 Cookie

	/**
	 * 获取所有Cookie
	 *
	 * @param request
	 */
	public void getCookies(HttpServletRequest request) {
		// 通过 HttpServletRequest 就能获取所有的Cookie
		Cookie[] cookies = request.getCookies();
		if (cookies != null) {
			for (int i = 0; i < cookies.length; i++) {
				System.out.println("Cookie 名称: " + cookies[i].getName());
				System.out.println("Cookie 值: " + cookies[i].getValue());
				System.out.println("Cookie 存在的路径: " + cookies[i].getPath());
				System.out.println("Cookie 域: " + cookies[i].getDomain());
				System.out.println("Cookie 过期时间: " + cookies[i].getMaxAge());
				System.out.println("Cookie 安全性: " + cookies[i].getSecure());
				System.out.println(); 
			}
		}
	}

根据名称获取指定 Cookie

	/**
	 * 根据名称获取指定Cookie
	 * 
	 * @param request
	 * @param name Cookie的名称
	 * @return
	 */
	public Cookie getCookieByName(HttpServletRequest request, String name) {
		// 通过 HttpServletRequest 就能获取Cookie
		Cookie[] cookies = request.getCookies();
		if (cookies == null) {
			return null;
		}
		for (int i = 0; i < cookies.length; i++) {
			if (name.equals(cookies[i].getName())) {
				return cookies[i];
			}
		}
		return null;
	}

添加 Cookie

	/**
	 * 创建 Cookie
	 * @param response 
	 * @param name Cookie的名称
	 * @param value Cookie的值
	 */
	public void createCookie(HttpServletResponse response, String name, String value) { 
		Cookie cookie = new Cookie(name.trim(), value.trim());
		cookie.setHttpOnly(true);// 如果设置了"HttpOnly"属性,那么通过程序(JS脚本、Applet等)将无法访问该Cookie
		cookie.setMaxAge(60 * 60);// 设置生存期为1小时
		cookie.setDomain("/");// 子域,在这个子域下才可以访问该Cookie
		cookie.setPath("/cookieServlet");// 在这个路径下面的页面才可以访问该Cookie
		cookie.setSecure(true);// 如果设置了Secure,则只有当使用https协议连接时cookie才可以被页面访问
		response.addCookie(cookie);
	}

通过名称删除指定的 Cookie


	/**
	 * 通过名称删除指定的 Cookie
	 * 
	 * 如果max-age属性为正数,则表示该cookie会在max-age秒之后自动失效。浏览器会将max-age为正数的cookie持久化,即
	 * 写到对应的cookie文件中。无论客户关闭了浏览器还是电脑,只要还在max-age秒之前,登录网站时该cookie仍然有效。
	 * 
	 * 如果max-age属性为负数,则表示该cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该cookie即失效。max-age
	 * 为负数的Cookie,为临时性cookie,不会被持久化,不会被写到cookie文件中。cookie信息保存在浏览器内存中,因此关闭浏览器该
	 * cookie就消失了。cookie默认的max-age值为-1。
	 * 
	 * 如果max-age属性为0,则表示删除该cookie。cookie机制没有提供删除cookie的方法,因此通过设置该cookie即时失效实现删除cookie的效果。
	 * 失效的Cookie会被浏览器从cookie文件或者内存中删除。
	 * 
	 * 
	 * @param request
	 * @param response
	 * @param name Cookie的名称
	 */
	public void deleteCookie(HttpServletRequest request, HttpServletResponse response, String name) {
		// 通过 HttpServletRequest 就能获取Cookie
		Cookie[] cookies = request.getCookies();
		if (cookies != null) {
			for (int i = 0; i < cookies.length; i++) {
				// 就将value设置为null,将存活时间设置为0,再替换掉原cookie,这样就相当于删除了。
				if (name.equals(cookies[i].getName())) {
					Cookie cookie = cookies[i];
					cookie.setMaxAge(0);
					response.addCookie(cookie);
				}
			}
		}
	}

编辑操作和删除操作一样,但是需要注意的是修改、删除Cookie时,除value、maxAge之外的所有属性,例如name、path、domain等,都要与原Cookie完全一样。否则,浏览器将视为两个不同的Cookie不予覆盖,导致修改、删除失败。

cookie和session的区别

cookie是存在客户端浏览器上,session会话存在服务器上。会话对象用来存储特定用户会话所需的属性及配置信息。当用户请求来自应用程序的web页时,如果该用户还没有会话,则服务器将自动创建一个会话对象。当会话过期或被放弃后,服务器将终止该会话。cookie和会话需要配合,具体内容参见1.1节。

当cookie失效、session过期时,就需要重新登录了。

在浏览器中查看 Cookie

在浏览器中如果想要查看和编辑当前页面的 Cookie,可以使用如下的Chrom插件 EditThisCookie

EditThisCookie是一个cookie管理器。您可以添加,删除,编辑,搜索,锁定和屏蔽cookies!
针对Google Chrome浏览器的第一个也是最棒的cookie管理器。
★ 编辑cookies
★ 删除cookies
★ 添加一个新的cookie
★ 创建cookies
★ 搜索cookies
★ 保护cookies (只读cookies)
★ 拦截cookies (cookie 过滤器)
★ 导出cookies为JSON, Netscape cookie 文档 (非常适合wget及curl), Perl::LPW
★ 导入JSON格式cookies
★ 限制任何cookie的最大有效期
★ 改进性能,移除旧的cookies
★ 导入cookies.txt
EditThisCookie Chrom商店

  • 使用界面
    EditThisCookie 使用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值