Cookie 没你不行

Cookie 没你不行

前言:

你知道吗,当有人悄悄的禁用了你浏览器的cookie,一场灾难将会发生,若是你不是一个开发人员,那更是灾难。 
笔者在写这篇文章前作了下实验,BAT所有登陆不了,只有baidu给了我的性化的提示:Alt text 
既然cookie如此重要,你真的对它了解吗?javascript

起源

讲这个仍是得先讲讲cookie是如何诞生的,由于HTTP协议是无状态的,即服务器不知道用户上一次作了什么,这严重阻碍了交互式Web应用程序的实现。因而有这么一我的,网景公司的前雇员卢·蒙特利在1993年3月的发明了cookie。最初在1997年2月定义于 RFC 2109,后来有两次更新,于2000年10月的RFC2965和2011年4月RFC6265。 
你能够发现这几个文档的标题都是: HTTP State Management Mechanism (http 状态管理机制) 。 
讲到这里,有没有以为cookie 是一个神奇的存在, 1993年发明的,一直用到如今 ,虽然互联网技术突飞猛进,但它仍是保留下来,而且不可或缺,rfc文档 也有两次更新 。css

究竟是什么?

Cookie 是服务器保存在浏览器的一小段文本信息。这是个纯文本的信息,而且按照协议规定的格式来存储 。浏览器每次向服务器发出请求,就会自动附上这段信息,因而Web 服务器就可使用这些信息来识别不一样的用户 。生活中咱们使用的大部分须要登陆的网站,登陆成功后都会设置一个cookie到浏览器,只要这个cookie 存在,用户就能够浏览网站的任意页面,手动清理掉这个cookie,就至关于退出登陆。 这也就是为何前言中会出现:若是禁用浏览器cookie功能,大部分网站就没法登陆,没法使用须要登陆后才能使用的功能了。html

使用场景

会话(session)管理:保存登陆、购物车等须要记录的信息。 
个性化:保存用户的偏好,好比网页的字体大小、背景色、地域等等。 
追踪:记录和分析用户行为,广告。java

这里有必要提一下,浏览器对单个cookie的大小,一个网站的cookie个数,总的大小和个数都有限制,其实cookie不适合用来做为大量数据的客户端存储,如过须要这个功能,可使用浏览器的Local Storage 、IndexDB等新的功能来替代,这里就不作延展。jquery

cookie的缺陷 
Cookie会被附加在每一个HTTP请求中,因此无形中增长了流量。 
因为在HTTP请求中的Cookie是明文传递的,因此安全性成问题,除非用HTTPS。 
Cookie的大小限制在4KB左右,数量在20左右,对于复杂的存储需求来讲是不够用的。程序员

如何使用cookie

Cookie其实是由浏览器在管理(浏览器放出接口),这个问题就变成如何指挥浏览器增删改查cookie ,咱们知道浏览器是遵照http协议的,还有另外一方web服务端也是遵照的。咱们能够经过这个来指挥浏览器操做cookie。web

服务端要操做cookie是经过响应头:Set-Cookie , 浏览器接受到这个响应头 ,就至关于收到命令去操做cookie ,具体是添加cookie ,删除cookie 仍是修改cookie 要看后面的值 ,一个Set-Cookie 响应头自能操做一个cookie ,一个响应能够有多个Set-Cookie响应头 ,这样一次响应就能操做多个cookie, 
响应头中的cookie实例: 
Set-Cookie:ykjjdc=c89e252fb3ce3cf203f; domain=.jjw.com; expires=Mon, 21-Mar-2118 07:00:11 GMT; path=/ 
用 “;” 分隔的字符串,每一段基本是一个键值对。 
服务端要获取cookie 是经过 请求头: Cookie ,http协议规定浏览器每次发起一个请求,要筛选符合要求的cookie(好比域相同,路径相同,没过时等)放在请求头Cookie中 传递给服务端 。 
请求头中的Cookie实例: 
Cookie: cna=UfdnD69NHXgE8g; UM_distinctid=16223df34200 
能够到也是用 “;” 分隔的字符串, 没一段就是一个cookie ,忽略了cookie的其余属性,也就是说服务端不知道这个cookie是谁写的,何时将会过时。chrome

document.cookie 是客户端读写cookie的惟一接口 ,这个属性可读可写 。 
读的状况下,返回当前脚本路径下全部的cookie(不包含属性包好httponly的),按照相关性排序(解决不一样路径下相同名字cookie的问题)。读出来的示例: 
iddc=fsfea; fsf=3; yssskjjdc=ssfe; ykjjdc=fsa浏览器

写的状况下,一次只能写一个cookie,不会覆盖已有cookie ,根据你写的内容,会出现 添加一个cookie ,修改一个cookie ,删除一个cookie等不一样的结果 。 
写的示例以下:安全

document.cookie = "foo=bar; expires=Fri, 31 Dec 2020 23:59:59 GMT";

能够看出都是对字符串的处理,这种处理容易出错,目前比较流行的cookie帮助类有 jquery.cookie.js 和yui中的对cookie的相关函数。能够方便的读写cookie。

不一样服务端代码中对cookie封装的原理就是 基于 http协议中的cookie机制 ,上文中有提到,asp.net 也不例外。 
asp.net 中有一个类 System.Web.HttpCookie 来对应cookie ,咱们来看看他的结构

HttpCookie 属性 cookie 原生属性 描述
Domain domain 获取或设置要将与 cookie 相关联的域。
Expires expires 获取或设置的过时日期和时间的 cookie。
HasKeys 获取一个值,该值指示 cookie 是否有子项。subcookies应用
HttpOnly httponly 获取或设置一个值,指定 cookie 是由客户端脚本访问。
Name name 获取或设置 cookie 的名称。
Path path 获取或设置要与当前 cookie 传输的虚拟路径。
Secure secure 获取或设置一个值,该值指示是否传输,即经过 HTTPS 仅使用安全套接字层 (SSL)-的 cookie。
Value value 获取或设置一个单独的 cookie 值。
Values 获取包含在一个 cookie 对象内的键/值对的集合。subcookies,解决cookie个数过多问题
max-age 对 expires属性的补充 ,存在浏览器兼容性问题
host-only 强制域彻底一致才可访问

经过上表咱们能够看到 ,原生cookie的属性基本和aspnet 中的一致。 
咱们能够经过Request.Cookies 获得请求头中的cookie ,而且能够很方便的拿到对应的值 , 
(有兴趣的朋友能够研究下 ,有相同的cookie名时服务端的取值状况 )。

在aspnet 中服务端能够经过下面的对象或者语法方便的操做cookie 。

Response.AppendCookie()
Response.AppendHeader("Set-Cookie" ,"iron=fage");
Response.SetCookie()
Response.Cookie.Add()

可是笔者认为这个设计还不如 JavaScript中 cookie 的操做设计,一个属性增删改查全是它 。 
这样的封装设计干扰了程序员对cookie的学习了解。

web.config 关于cookie的全局配置节点 , 你能够指定cookie的域 ,固然这个域必须和地址栏中的主域一致; 也能够为了安全起见配置httpOnlyCookies 使默认输出的cookie 都是js不能读取操做的 ; 还能够配置 requireSSL 是浏览器只有在https地址上发送这个cookie (这个的前提也是当前协议是用的https)。

<httpCookies domain="String"
httpOnlyCookies="true|false"
requireSSL="true|false" />

工做中,除了浏览器发起http请求外, 还有一种状况是本身编写代码来发起http请求,好比对第三方http接口的请求。

CookieContainer cookieContainer = new CookieContainer();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "GET";
request.CookieContainer = cookieContainer; //这个属性用来传递cookie
 
using( WebResponse response = request.GetResponse() ) {
using( StreamReader reader = new StreamReader(response.GetResponseStream(), encoding) ) {
return reader.ReadToEnd();
}
}
//执行上面的代码后,若是http响应中有cookie,将会追加到 cookieContainer ;

Cookie最核心的应用应该就是做为会话机制了,正如前言中提到的,浏览器停掉cookie ,大部分网站都没法登陆的数据。 其实 asp.net 中的 Session[“”] 默认配置下,就依赖于cookie ,会在客户端用cookie存储一个sessionid 。

Cookie最多见的应用还有 ,记录用户的使用偏好 ,好比用户 经常使用城市, 语言 ,网站主题,字体等 , 固然这些均可以存储服务端和用户信息关联 ,可是若是网站不须要登陆,这些数据存储在服务端就不合适了。

还有吗?

工具

浏览器自己就会提供cookie 的开关配置,用户能够根据本身须要来开启或者关闭,或者开启部分网站,关闭部分网站等设置 。 
浏览器也会提供cookie的管理工具 , 可是大都不是很好用 。 chrome 内核浏览器 的开发人员工具能够很方便的查看cookie 可是管理就不是很便利了 。 
浏览器插件是解决这个问题的终极方案, EditThisCookie 这款浏览器插件是个不错的选择。

Q&A

  • 若是你须要写一个浏览器,你须要对cookie 作哪些处理
  • 接口化开发,对于接口的响应中的cookie如何处理 。
  • 除了经过 set-Cookie ,JavaScript 操做cookie ,还有其余方式吗
  • 向图片,css ,js 发出的请求 会携带cookie 吗
  • 说说cookie 的缺点
  • 对咱们工做的启发 ?

Thanks

资料

相关文章
相关标签/搜索