前言
这篇文章实话说我有点虚,因为平时都不怎么研究这一块的,然后涉及到的知识点超多,我只能到处看看资料总结一下相关信息,所以在此我只想说句:
本文章内容只代表个人立场,有错必改!
原本打算一次性总结,后来越扯越多超过字数限制了,就干脆做成http系列文章了,不定时更新原有内容(发现哪里出错的话),不定时新增系列文章,请见谅!
因为之前写得太臃肿又不够详细,最近刚好复习到这一块的内容,所以决定把这些文章都拆分成更加细致一点,补充详细内容,优化排版布局,目前来看还是应该的,因为自身时间问题和平台编译的问题迟迟未改,只好等都改完之后才发出来。
网络协议系列 — TCP、UDP、SOCKET与参考模型
Cookie
服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。通常,它用于告知服务端两个请求是否来自同一浏览器,主要应用方面:
- 会话状态管理(如用户登录状态、购物车、游戏分数或其它需要记录的信息)
- 个性化设置(如用户自定义设置、主题等)
- 浏览器行为跟踪(如跟踪分析用户行为等)
注意: 服务器指定Cookie后,浏览器的每次请求都会携带Cookie数据,会带来额外的性能开销。
设置Set-Cookie属性
需要传输的自定义键值对数据 cookie-name=cookie-value:
- cookie-name 可以是除了控制字符 (CTLs)、空格 (spaces) 或制表符 (tab)之外的任何 US-ASCII 字符。同时不能包含以下分隔字符:( ) < > @ , ; : " / [ ] ? = { }.
cookie-value 是可选的,如果存在的话,那么需要包含在双引号里面。支持除了控制字符(CTLs)、空格(whitespace)、双引号(double quotes)、逗号(comma)、分号(semicolon)以及反斜线(backslash)之外的任意 US-ASCII 字符。
- 关于编码:许多应用会对 cookie 值按照URL编码(URL encoding)规则进行编码,但是按照 RFC 规范,这不是必须的。不过满足规范中对于 <cookie-value> 所允许使用的字符的要求是有用的。
- __Secure- 前缀:以
__Secure-
为前缀的 cookie(其中连接符是前缀的一部分),必须与 secure 属性一同设置,同时必须应用于安全页面(即使用 HTTPS 访问的页面)。 - __Host- 前缀:以
__Host-
为前缀的 cookie,必须与 secure 属性一同设置,必须应用于安全页面(即使用 HTTPS 访问的页面),必须不能设置 domain 属性 (也就不会发送给子域),同时 path 属性的值必须为“/”。
配置属性如下:
属性 | 描述 |
---|---|
Domain | 指定 cookie 可以送达的主机名。假如没有指定,那么默认值为当前文档访问地址中的主机部分(但是不包含子域名)。与之前的规范不同的是,域名之前的点号会被忽略。假如指定了域名,那么相当于各个子域名也包含在内了 |
Path | 指定一个 URL 路径,这个路径必须出现在要请求的资源的路径中才可以发送 Cookie 首部。字符 %x2F ("/")可以解释为文件目录分隔符,此目录的下级目录也满足匹配的条件(例如,如果 path=/docs,那么 "/docs","/docs/Web/" 或者 "/docs/Web/HTTP" 都满足匹配的条件) |
Expire time | cookie 的最长有效时间,形式为符合 HTTP-date 规范的时间戳。参考 Date 可以获取详细信息。如果没有设置这个属性,那么表示这是一个会话期 cookie 。一个会话结束于客户端被关闭时,这意味著会话期 cookie 在彼时会被移除。然而,很多Web浏览器支持会话恢复功能,这个功能可以使浏览器保留所有的tab标签,然后在重新打开浏览器的时候将其还原。与此同时,cookie 也会恢复,就跟从来没有关闭浏览器一样。 |
Max-age | 在 cookie 失效之前需要经过的秒数。一位或多位非零(1-9)数字。一些老的浏览器(ie6、ie7 和 ie8)不支持这个属性。对于其他浏览器来说,假如二者 (指 Expires 和Max-Age)均存在,那么 Max-Age 优先级更高 |
secure | 一个带有安全属性的 cookie 只有在请求使用SSL和HTTPS协议的时候才会被发送到服务器。然而,保密或敏感信息永远不要在 HTTP cookie 中存储或传输,因为整个机制从本质上来说都是不安全的,比如前述协议并不意味著所有的信息都是经过加密的。 |
httponly | 设置了 HttpOnly 属性的 cookie 不能使用 JavaScript 经由 Document。cookie 属性、XMLHttpRequest 和 Request APIs 进行访问,以防范跨站脚本攻击(XSS)。 |
注意
- Cookie默认的maxAge值为–1;
- 如果为正数,则表示该Cookie会在maxAge秒之后自动失效。浏览器会将maxAge为正数的Cookie持久化,即写到对应的Cookie文件中。无论客户关闭了浏览器还是电脑,只要还在maxAge秒之前,登录网站时该Cookie仍然有效;
- 如果为负数,则表示该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效。maxAge为负数的Cookie,为临时性Cookie,不会被持久化,不会被写到Cookie文件中。Cookie信息保存在浏览器内存中,因此关闭浏览器该Cookie就消失了;
- 如果maxAge为0,则表示删除该Cookie。Cookie机制没有提供删除Cookie的方法,因此通过设置该Cookie即时失效实现删除Cookie的效果。失效的Cookie会被浏览器从Cookie文件或者内存中删除:
例子
Set-Cookie: sessionid=38afes7a8; HttpOnly; Path=/
Set-Cookie: id=a3fWa; Expires=Wed,21 Oct 2015 07:28:00 GMT; Secure; HttpOnly
类别
会话期Cookie
- 浏览器关闭之后它会被自动删除,不需要指定过期时间(Expires)或者有效期(Max-Age);
- 有些浏览器提供了会话恢复功能,这种情况下即使关闭了浏览器,会话期Cookie也会被保留下来;
- 持久性Cookie
指定一个特定的过期时间(Expires)或有效期(Max-Age); Secure和HttpOnly 标记
- 安全的Cookie只应通过HTTPS协议加密过的请求发送给服务端;
- 为避免跨域脚本 (XSS)攻击,通过JavaScript的 Document。cookie API无法访问带有 HttpOnly 标记的Cookie;
- 僵尸Cookie
这类Cookie较难以删除,甚至删除之后会自动重建。它们一般是使用Web storage API、Flash本地共享对象或者其他技术手段来达到的
安全问题
- 会话劫持和XSS
- 跨站请求伪造(CSRF)
Cookie的实现
- Javascript调用document。cookie
服务器发送
- 服务器端在响应中利用Set-Cookie header来创建一个Cookie,发送给客户端;
- 客户端将Cookie保存到某个目录下的文本文件内;
- 如果客户端支持Cookie,下次请求同一网站时就可以Cookie直接发送给服务器;
优点:
- 能跟踪用户的整个会话,确定用户身份;
- 具有不可跨域名性(即使同一个父域也不行,但有办法实现);
缺点:
- 需要浏览器支持或者启用;
- 部分情况需要将数据编码(Unicode字符在内存中占4个字符,而英文属于ASCII字符在内存中只占2个字节,前者如中文就需要编码,否则乱码);
- 每次请求都会发送该域名下的所有cookie,即使不需要用到;
- 修改、删除Cookie时,新建的Cookie除value、maxAge之外的所有属性,都要与原Cookie完全一样。否则,浏览器将视为两个不同的Cookie不予覆盖,导致修改、删除失败;
- 明文传递,不适合保存重要数据;
- 长度限制,不适合保存复杂数据;
Web Storage
Html5提供了本地缓存功能local storage和session storage,这个不算http东西我就不说了,看看文档就懂。
优点:
- 良好的API,即拿即用,使用简单;
- 无需请求,节省宽带资源;
- 读取速度快;
- session storage浏览器关闭就移除,适合临时数据;
缺点:
- 不适合储存改动频繁数据;
- local storage或者用户手动移除,否则永远存在;
(更多内容请自行查阅,本节到此为止了。)
Session
如果说Cookie技术是通过客户端来保持状态的解决方案,Session技术则是通过服务器来保持状态的解决方案。
浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上。这就是Session。客户端浏览器再次访问时只需要从该Session中查找该客户的状态就可以了,相当于做了一层个人档案。而Session ID是唯一标识。
服务器会为每一个访问服务器的用户创建一个session对象,并且把session对象的id保存在本地cookie上,只要用户再次访问服务器时,带著session的id,服务器就会匹配用户在服务器上的session,根据session中的数据,还原用户上次的浏览状态或提供其他人性化服务。Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session“活跃(active)”了一次。为了解决大量session占用服务器资源的问题,可以设置一个超时设置,当用户活跃时间间隔超过超时设置,该session会被移除。
如果客户端浏览器将Cookie功能禁用,可以使用URL地址重写,原理是将该用户Session的id信息重写到URL地址中。服务器能够解析重写后的URL获取Session的id。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态
优点
- 使用比cookie方便;
- 能还原用户上次的浏览状态或提供其他人性化服务;
缺点
- Session会占用服务器内存中,请求高压情况下有内存溢出的隐患;
- 需要cookie保存session的关联id(能通过URL地址重写技术解决方案);
因为这个是服务器的东西,我接触不多,就说一些原理差不多了。
(更多内容请自行查阅,本节到此为止了。)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。