Cookie的类型

会话cookie和持久cookie

会话cookie是一种临时cookie,它记录了用户访问站点时的设置和偏好,当用户退出浏览器时,会话cookie就会被删除。

持久cookie的生存时间更长一些,它存储在用户的硬盘上,浏览器退出或计算机重启时他们仍然存在。

会话cookie与持久cookie之间的唯一区别就是它们的过期时间。

如果设置了Discard参数(cookie版本1中的参数),或者没有设置Expires或者Max-Age参数(cookie版本1中的参数)来说明扩展的过期时间,这个cookie就是一个会话cookie。

Cookie是如何工作的

Cookie可以通过服务器进行设置,相当于服务器给用户贴的一个标签,用于跟踪用户的状态。

通过服务器设置的cookie信息通过响应头返回给浏览器,浏览器将响应头中的cookie信息保存在本地,当下次向服务器发送HTTP请求时,就自动将保存的这些cookie信息添加到请求头中(包含通过document.cookie接口设置的cookie)。

下面是退出博客园登录时的响应头和请求头,响应头中有Set-Cookie字段,请求头中有Cookie字段:

通过BOM提供的document.cookie接口,在前端可以对cookie进行操作(增、删、改),本质上是对符合一定规律的一个字符串进行操作,这样开发人员就可以利用cookie在本地存储一些数据。当然,建议存储一些非敏感信息。

Cookie的限制和组成

Cookie的限制

Cookie的限制主要有两条:

  1. 访问cookie时的同源限制
  2. Cookie的个数和尺寸限制

同源限制

Cookie在性质上是绑定在特定的域名下的。当创建了一个cookie后,再给创建它的域名发送请求时,请求头中都会包含这个cookie。这个限制确保了储存在cookie中的信息只能让批准的域访问,而无法被其他域访问。

个数和尺寸限制

每个域名下可绑定的cookie的个数是有限的,不同浏览器所限制的个数不同。

浏览器对同域名下cookie个数的限制见下表:

浏览器

可绑定的cookie的个数

IE6

20

IE7

50

Firefox

50

Opera

30

Safari

没有硬性限制

Chrome

没有硬性限制

当超过单个域名限制之后还要再设置cookie,浏览器就会清除以前设置的cookie。

浏览器中对于单个cookie的尺寸也有限制,一般限制在4KB。尺寸限制影响到一个域名下的所有cookie,而并非每个cookie单独限制。

Cookie的组成

名称和值 name = value:必填。name和value都是字符序列,除非包含在双引号内,否则不包括分号、逗号、等号和空格。Web服务器可以创建任意的name=value关联,浏览器在后继对站点的访问中会将其送会给web服务器。

域  domain:可选。表示该cookie对于哪个域是有效的。所有向该域发送的请求中都会包含这个cookie信息。这个值可以包含子域(如www.wrox.com,表示该cookie信息只向该域名发送),也可以不包含(如.wrox.com,则对于wrox.com的所有子域都有效)。如果没有明确规定,那么这个域会被认作来自设置该cookie的那个服务器所在的域。

路径  path:可选。通过这个字段可以为服务器上特定的文档分配cookie。如果path字段是一个URL路径前缀,就可以附加一个cookie。例如:路径 /foo与 /foobar和 /foo/bar.html相匹配。路径 / 与域名中的所有内容都匹配。默认值是设置 Cookie 时的当前目录。

失效时间  expires(新版的cookie规范中是max-age字段):可选。这个字段会指定一个日期字符串,用来定义cookie的实际生存期。一旦到了这个日期,就不再存储或发布这个cookie了,该cookie就会被删除。如果设置的日期是以前的时间,则cookie会被立刻删除。

日期格式为GMT格式:Wdy, DD-Mon-YYYY HH:MM:SS GMT。

安全标志  secure:可选。该字段不是键值对的形式,如果要指定该字段,只要在设置cookie时添加secure字符即可。设置了该字段后,该cookie只有在使用SSL连接的时候才发送到服务器。例如:指定域为www.wrox.com的cookie,在制定了secure字段后,该cookie只能发送给https://www.wrox.com,而发送给http://www.wrox.com的请求不会添加该cookie。

HTTP专用  HttpOnly:可选。该字段只能在服务端设置,表示该cookie是否能通过JS(BOM的document.cookie接口)去访问。默认情况下HttpOnly字段为空,表示可以通过JS访问该cookie。

按照规范,开发人员无法利用JS在前端修改cookie的HttpOnly字段,不过有的浏览器没有这个限制,具体看这篇文章:浏览器中因cookie设置HttpOnly标志引起的安全问题

关于如何在服务端设置该字段,请看这篇文章:关于Cookie安全性设置的那些事

注意:域、路径、失效时间、安全标志(secure)和HttpOnly字段都是服务器给浏览器的指示,告诉浏览器如何存储和发送cookie,这些参数并不会作为发送到服务器的cookie信息的一部分,只有cookie中的名值对儿(name=value)才会被发送。

在前面的图片中,响应头中的一个Set-Cookie就代表一个cookie;请求头中的Cookie字段中可以包含多个cookie的名值对儿,而不是仅包含一个cookie的名值对儿。

BOM的document.cookie接口

当用来获取cookie时,document.cookie返回当前页面可用的所有cookie的字符串,一系列由分号隔开的名值对儿。

例如,我在Chrome中打开这个页面:https://segmentfault.com/a/1190000004556040,在控制台中输入以下代码:

console.log(document.cookie);

控制台中会输出以下结果:

PHPSESSID=web2~f57e474e4a8mc396h4du05qsa0;
Hm_lvt_e23800c454aa573c0ccb16b52665ac26=1495500966;
Hm_lpvt_e23800c454aa573c0ccb16b52665ac26=1495500966;
_ga=GA1.2.1399344530.1495500966;
_gid=GA1.2.584865054.1495500966;
showRegister2=true;
showRegister=false

有七个由分号分隔得名值对儿,表示有七个cookie可用(所有名字和值都是经过URL编码的,所以必须使用decodeURIComponent()来解码。)。

点击开发者工具中的Application选项,在左边找到Cookies下拉菜单,点击第一个域名,就可以看到这七个cookie的详细信息。具体如下:

当用于设置cookie时,document.cookie可以设置一个新的cookie字符串,这个cookie字符串会被解释并添加到当前现有的cookie集合中。其中名值对儿(name=value)是必须的(最好用encodeURIComponent()对name和value进行编码),其它字段在cookie的组成部分已做过介绍。

通过document.cookie设置的cookie并不会覆盖现有的cookie,除非设置的cookie的name在现有cookie集合中已经存在,并且path/domain/secure这几个选项一定要和旧cookie 保持一样。否则不会修改旧cookie,而是添加了一个新的 cookie。

例子(使用wamp环境):

PHP代码:

<?php setcookie("abc", "test",null, '/' );   ?>

HTML代码:

<button id="btn" type="button" value="submit">发送请求</button>
<button id="display-cookie" type="button" value="submit">显示cookie</button>
<button id="reset-cookie" type="button" value="submit">设置cookie</button>

JS代码:

function myAJAX(url) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
console.log(xhr.responseText);
console.log(xhr.responseXML);
} else {
console.log(xhr.statusText);
console.log(xhr.status);
}
}
};
xhr.open("get",url,true);//true表示异步,false表示同步
//此处设置头部信息 xhr.send(null);
}
function init(){
var btn = document.getElementById('btn');
var displayCookie = document.getElementById('display-cookie');
var resetCookie = document.getElementById('reset-cookie');
var removeCookie = document.getElementById('remove-cookie');
btn.addEventListener('click',function(event) {
var url = 'cookie.php';
myAJAX(url);
},false); displayCookie.addEventListener('click',function(event) {
console.log(document.cookie);
},false); resetCookie.addEventListener('click',function(event) {
document.cookie = "abc=ok;path=/"
},false);
}
init();

第一次打开该页面时,点击显示cookie按钮,控制台无输出内容,谷歌开发者工具中Application选项卡中的cookie选项中也为空。

点击发送请求按钮,在Network选项卡中查看头部信息:

在Application选项卡中的cookies选项查看cookie:

现在点击显示cookie按钮:

只显示出了名值对儿,没有显示该cookie的其它字段的信息。

接下来点击设置cookie按钮,重设该cookie,然后再点击显示cookie按钮:

该cookie的值被重设为了ok。

我们再点击发送请求按钮,看看这一次请求的头部信息:

请求头中的Cookie字段是浏览器发送给服务器的cookie信息,cookie的值之前被我们设置为了ok。响应头中的Set-Cookie字段是服务器返回给浏览器的cookie信息(实际上这时,cookie的值又被设置为了test)(我只是描述这个现象,不知道理解的对不对。)。

没有删除已有cookie的直接方法。所以,需要使用相同的路径(path)、域(domain)和安全选项(secure)再次设置原cookie,并将失效时间设置为过去时间

通过document.cookie设置的cookie也会被浏览器添加到请求头中。

举例,用document.cookie设置cookie:

document.cookie = encodeURIComponent(“username”) + “=” +
encodeURIComponent(“jack”) + “; domain=.wrox.com; path=/”;

子cookie

子cookie是存放在单个cookie中的更小段的数据。也就是使用cookie值来存储多个名值对儿。

一种子cookie的格式:

name=name1=value1&name2=value2&name3=value3&name4=value4

本质上还是字符串的操作。

CORS中的cookie

(摘自阮一峰老师的文章:跨域资源共享 CORS 详解

CORS请求默认不发送Cookie和HTTP认证信息。如果要把Cookie发到服务器,一方面要服务器同意,指定Access-Control-Allow-Credentials字段为true。另一方面,开发者必须在AJAX请求中打开XMLHttpRequest对象的withCredentials属性。否则,即使服务器同意发送Cookie,浏览器也不会发送。或者,服务器要求设置Cookie,浏览器也不会处理。

但是,如果省略withCredentials设置,有的浏览器还是会一起发送Cookie。这时,可以显式关闭withCredentials。

需要注意的是,如果要发送Cookie,Access-Control-Allow-Origin就不能设为星号,必须指定明确的、与请求网页一致的域名。同时,Cookie依然遵循同源政策,只有用服务器域名设置的Cookie才会上传,其他域名的Cookie并不会上传,且(跨源)原网页代码中的document.cookie也无法读取服务器域名下的Cookie。

写在后面的话:

上面关于cookie的总结,仅仅是我了解到的关于cookie的知识。

关于cookie的规范:

https://tools.ietf.org/html/rfc6265

参考文章:

1、聊一聊 cookie

2、http://php.net/manual/zh/function.setcookie.php

3、HTTP权威指南第11章

4、Javascript高级程序设计(第三版)第23章

相关文章:

1、漫谈Cookie安全

2、Cookie/Session机制详解

3、Document.cookie MDN

关于Cookie的知识的总结的更多相关文章

  1. web跨域及cookie相关知识总结

    原文:web跨域及cookie相关知识总结   之前对于跨域相关的知识一致都很零碎,正好现在的代码中用到了跨域相关的,现在来对这些知识做一个汇总整理,方便自己查看,说不定也可能对你有所帮助. 本篇主要 ...

  2. Session & Cookie小知识~

    Cookie 一个HTTP cookie的(也称为网络Cookie,互联网的cookie,浏览器cookie,或者干脆饼干)是一小块从发送的数据的网站用户的并存储在用户的计算机上的网页浏览器,而用户浏 ...

  3. session和cookie相关知识总结

    HTTP协议本身是无状态的,这与HTTP协议本来的目的是相符的,客户端只需要简单的向服务器请求下载某些文件,无论是客户端还是服务器都没有必要纪录彼此过去的行为,每一次请求之间都是独立的. 人们很快发现 ...

  4. session和cookie的知识总结

    1.HTTP协议 由HTTP客户端发起一个请求,建立一个到服务器指定端口(默认是80端口)的TCP连接.HTTP服务器则在那个端口监听客户端发送过来的请求.一旦收到请求,服务器(向客户端)发回一个状态 ...

  5. JavaScript 操作 Cookie

    转自作者:聂微东出处:http://www.cnblogs.com/Darren_code/      什么是 Cookie “cookie 是存储于访问者的计算机中的变量.每当同一台计算机通过浏览器 ...

  6. cookie的一些细节

    什么是 Cookie “cookie 是存储于访问者的计算机中的变量.每当同一台计算机通过浏览器请求某个页面时,就会发送这个 cookie.你可以使用 JavaScript 来创建和取回 cookie ...

  7. JavaScript之Cookie讲解

    什么是 Cookie “cookie 是存储于访问者的计算机中的变量.每当同一台计算机通过浏览器请求某个页面时,就会发送这个 cookie.你可以使用 JavaScript 来创建和取回 cookie ...

  8. Cookie介绍及JavaScript操作Cookie方法详解

    本文主要为大家简单介绍了以下Cookie的用途.运行机制,以及JavaScript操作Cookie的各种方法,总结的比较全面,希望能给大家带来帮助. 什么是 Cookie “cookie 是存储于访问 ...

  9. Cookie概念

    ASP.NET Cookie概念.CURD操作.原理.实际运用   会话就WEB开发来说,一个会话就是你通过浏览器与服务器之间的一次通话,只不过这种通话是以用浏览器浏览的方式来实现的. 就会话的应用来 ...

随机推荐

  1. C# Task 源代码(2)

    上篇已经讲到Task 的默认的TaskScheduler 为ThreadPoolTaskScheduler. 这时我们回到原来的task 的start方法,在代码最后,调用了 ScheduleAndS ...

  2. 腾讯云上PhantomJS用法示例

    崔庆才 前言 大家有没有发现之前我们写的爬虫都有一个共性,就是只能爬取单纯的html代码,如果页面是JS渲染的该怎么办呢?如果我们单纯去分析一个个后台的请求,手动去摸索JS渲染的到的一些结果,那简直没 ...

  3. 连接greenvpn 公司内网连接

    查看计算机路由表 Route print 跟踪路由表 Tracert ip or dnsname 本次需求,连接greenvpn之后,公司10.130.41.** 网段的机器无法使用.本机ip 10. ...

  4. Rookey.Frame v1.0极速开发平台稳定版发布

    Rookey.Frame v1.0经过一年时间的修改及沉淀,稳定版终于问世了,此版本经过上线系统验证,各个功能点都经过终端用户验证并持续优化,主要优化以下几个方面: 1.性能较原来提升3倍之多 2.修 ...

  5. .exe简单的更新软件demo

    百度网盘源码加文件:http://pan.baidu.com/s/1qYe2Vgg 功能:通过网站更新用户的软件,需要联网,也可以通过本地网站更新局域网用户软件. 根本实现:1.一个网站(本地就可以) ...

  6. nginx学习笔记——http module分析

         源码:nginx 1.12.0           nginx由于其高性能.扩充性好等特点在迅速走红,越来越多的公司采用nginx作web服务器.负载均衡.waf等 工作,一些基于nginx ...

  7. jwt token Example - Python

    0 Pre Install Python3 Install PyCrypto Install PyJWT 1 token 由三部分组成 header, payload, sign 并用逗号连接各部分 ...

  8. netty——私有协议栈开发案例

    netty--私有协议栈开发案例 摘要: 在学习李林峰老师的Netty权威指南中,觉得第十二章<私有协议栈开发>中的案例代码比较有代表性,讲的也不错,但是代码中个人认为有些简单的错误,个人 ...

  9. 跨语言学习的基本思路及python的基础学习

    笔者是C#出身,大学四年主修C#,工作三年也是C#语言开发.但在学校里其他的语言也有相应的课程,eg:Java,Php,C++都学过,当然只是学了皮毛(大学嘛,你懂得),严格来说未必入门,但这些语言的 ...

  10. 数据结构与算法(c++)——跳跃表(skip list)

    今天要介绍一个这样的数据结构: 单向链接 有序保存 支持添加.删除和检索操作 链表的元素查询接近线性时间 ——跳跃表 Skip List 一.普通链表 对于普通链接来说,越靠前的节点检索的时间花费越低 ...