Cookie详解

 
背景
在HTTP协议的定义中,采用了一种机制来记录客户端和服务器端交互的信息,这种机制被称为cookie,cookie规范定义了服务器和客户端交互信息的格式、生存期、使用范围、安全性。
 
Cookie格式
Cookie中保存的信息都是文本信息,在客户端和服务器端交互过程中,cookie信息被附加在HTTP消息头中传递,cookie的信息由键/值对组成。下面是一个HTTP头中cookie的例子:
Set-Cookie: key = value; Path=/
 
Cookie中存放的信息包含cookie本身属性和用户自定义属性,一个cookie只能包含一个自定义键/值对。Cookie本身属性有"Comment" 、"Domain"、"Max-Age"、"Path"、"Secure"、"Version"。
 
Comment属性是cookie的产生着对该cookie的描述;
 
Domain属性定义可访问该cookie的域名,对一些大的网站,如果希望cookie可以在子网站中共享,可以使用该属性。例如设置Domain为 .bigsite.com ,则sub1.bigsite.com和sub2.bigsite.com都可以访问已保存在客户端的cookie,这时还需要将Path设置为/。
 
Max-Age属性定义cookie的有效时间,用秒计数,当超过有效期后,cookie的信息不会从客户端附加在HTTP消息头中发送到服务端。
 
Path属性定义网站上可以访问cookie的页面的路径,缺省状态下Path为产生cookie时的路径,此时cookie可以被该路径以及其子路径下的页面访问;可以将Path设置为/,使cookie可以被网站下所有页面访问。
 
Secure属性值定义cookie的安全性,当该值为true时必须是HTTPS状态下cookie才从客户端附加在HTTP消息中发送到服务端,在HTTP时cookie是不发送的;Secure为false时则可在HTTP状态下传递cookie,Secure缺省为false。
 
Version属性定义cookie的版本,由cookie的创建者定义。
 
Cookie的创建
Cookie可以在服务器端创建,然后cookie信息附加在HTTP消息头中传到客户端,如果cookie定义了有效期,则本保存在客户端本地磁盘。保存cookie的文件是一个文本文件,因此不用担心此文件中的内容会被执行而破坏客户的机器。支持Web端开发的语言都有创建cookie的方法或函数,以及设置cookie属性和添加自定义属性的方法或函数,最后是将cookie附加到返回客户端的HTTP消息头中。
 
创建cookie时如果不指定生存有效时间,则cookie只在浏览器关闭前有效,cookie会在服务器端和客户端传输,但是不会保存在客户机的磁盘上,打开新的浏览器将不能获得原先创建的cookie信息。
 
Cookie信息保存在本地时会保存到当前登录用户专门目录下,保存的cookie文件名中会包含创建cookie所在页面网站的域名,当浏览器再次连接该网站时,会从本机cookie存放目录下选出该网站的有效cookie,将保存在其中的信息附加在HTTP消息头中发送到服务器端,服务器端程序就可根据上次保存在cookie的信息为访问客户提供“记忆”或个性化服务。
 
Cookie除了可以在服务器端创建外,也可以在客户端的浏览器中用客户端脚本(如javascript)创建。客户端创建的cookie的性质和服务器端创建的cookie一样,可以保存在本地,也可以被传送到服务器端被服务器程序读取。
Cookie的使用
从cookie的定义可以看到,cookie一般用于采用HTTP作为进行信息交换协议的客户端和服务器端用于记录需要持久化的信息。一般是由服务器端创建要记录的信息,然后传递到客户端,由客户端从HTTP消息中取出信息,保存在本机磁盘上。当客户端再次访问服务器端时,从本机磁盘上读出原来保存的信息,附加到HTTP消息中发送给服务器端,服务器端从HTTP消息中读取信息,根据实际应用的需求进行进一步的处理。
 
服务器端cookie的创建和再次读取功能通常由服务器端编程语言实现,客户端cookie的保存、读取一般由浏览器来提供,并且对cookie的安全性方面可以进行设置,如是否可以在本机保存cookie。
 
由于cookie信息以明文方式保存在文本文件中,对一些敏感信息如口令、银行帐号如果要保存在本地cookie文件中,最好采用加密形式。
其他
与cookie类似的另一个概念是会话(Session),会话一般是记录客户端和服务器端从客户端浏览器连接上服务器端到关闭浏览器期间的持久信息。会话一般保存在内存中,不保存到磁盘上。会话可以通过cookie机制来实现,对于不支持cookie的客户端,会话可以采用URL重写方式来实现。可以将会话理解为内存中的cookie。
 
使用会话会对系统伸缩性造成负面影响,当服务器端要在很多台服务器上同步复制会话对象时,系统性能会受到较大伤害,尤其会话对象较大时。这种情况下可以采用cookie,将需要记录的信息保存在客户端,每次请求时发送到服务器端,服务器端不保留状态信息,避免在服务器端多台机器上复制会话而造成的性能下降。
 
 
 
 
参考资料:
[2] JavaScript: The Definitive Guide, 4th Edition David Flanagan
[3] Core Servlets and JavaServer Pages™: Volume 1: Core Technologies, 2nd Edition Marty Hall, Larry Brown 
### Cookie 技术的全面解析 #### 什么是 CookieCookie 是一种小型文本文件,由服务器发送到用户的浏览器储在用户的设备上。它主要用于保会话状态、用户偏好设置或其他相关信息[^1]。 #### Cookie 的主要特点 - **持久化储**:某些类型的 Cookie 可以长期在,直到过期时间到达或被手动删除。 - **无状态协议的支持**:HTTP 协议本身是无状态的,而 Cookie 提供了一种机制来维护跨多个请求的状态信息。 - **安全性限制**:可以通过 `HttpOnly` 和 `Secure` 属性增强安全性和防止 XSS 攻击[^2]。 --- ### Spring 中如何使用 Cookie? #### 添加 Cookie 到响应头 通过 `javax.servlet.http.HttpServletResponse` 对象可以向客户端添加新的 Cookie: ```java import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; public void addCookie(HttpServletResponse response) { // 创建一个新的 Cookie 实例 Cookie cookie = new Cookie("username", "JohnDoe"); // 设置 Cookie 过期时间为一天(单位秒) cookie.setMaxAge(60 * 60 * 24); // 将 Cookie 路径设为根路径 "/" cookie.setPath("/"); // 向响应对象中添加该 Cookie response.addCookie(cookie); } ``` 此代码片段展示了如何创建一个名为 `username` 的 Cookie 并将其附加到 HTTP 响应头部。 #### 获取已在的 Cookie 从 `HttpServletRequest` 对象中读取现有的 Cookies: ```java import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; public String readCookie(HttpServletRequest request, String cookieName) { Cookie[] cookies = request.getCookies(); if (cookies != null && cookies.length > 0) { for (Cookie cookie : cookies) { if (cookie.getName().equals(cookieName)) { return cookie.getValue(); // 返回指定名称的 Cookie } } } return null; // 如果未找到对应名称的 Cookie,则返回 null } ``` 这段代码实现了遍历所有传入的 Cookies,并查找特定名称的 Cookie [^1]。 #### 删除 Cookie 要移除某个已经在的 Cookie,只需重新定义其最大活时间为零 (`setMaxAge(0)`): ```java public void deleteCookie(HttpServletResponse response, String cookieName) { Cookie cookie = new Cookie(cookieName, null); cookie.setMaxAge(0); // 立即失效 cookie.setPath("/"); // 需与原 Cookie 定义一致 response.addCookie(cookie); } ``` 注意这里设置了相同的路径属性 `/`, 因为只有相同路径下的 Cookie 才能被覆盖或者删除。 --- ### 测试场景中的注意事项 如果在一个多线程环境中运行自动化测试脚本时遇到问题,比如多次迭代过程中后续几次操作失败的情况,可能是因为重复利用了之前的 Session ID 或者其他形式的身份验证令牌作为 Cookie 储下来的结果[^4]。解决办法之一就是确保每次循环前清理掉旧有的 Cookies 数据再发起新连接尝试。 --- ### 性能优化建议 为了提高系统的性能以及减少不必要的网络流量传输开销,在实际项目开发当中应该遵循以下几个原则: 1. 不要在 Cookie放大容量的数据; 2. 使用 HTTPS 加密保护敏感型数据交换过程免受中间人攻击威胁; 3. 正确配置 `Domain` 参数避免子域名间互相干扰访问权限范围之外的内容资源加载行为发生意外错误状况出现等问题的发生几率降到最低限度以内为止就可以了嘛😊! ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值