cookie的产生
Web应用程序是使用HTTP协议传输数据的,HTTP协议是无状态协议,指协议对于交互没有记忆能力,浏览器与服务器的每一次交互都是新的。
为了使WEB应用程序在页面之间共享数据和记录用户状态,最早有两个解决方案cookie和Sesstion:
- cookie以文本格式存储在客户端;
- Sesstion存储在服务端。
cookie是网景公司发明的,服务器端向浏览器发送Cookie,浏览器将Cookie保存,浏览器能够获取到cookie,之后在浏览器与服务器交互时浏览器都会将cookie发送给服务器端。
这样使浏览器与服务器交互有了记忆功能,比如常用的用户登录状态,购物车等都可以存储在客户端。
目前所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持cookie,不同的浏览器对cookie的数目和大小的限制不同。一般来说每个web服务器(域名)保存的cookie数不能超过50个,每个cookie保存的数据不能超过4KB。
cookie是什么
cookie是一小段存储在浏览器端的文本信息。
cookie像是浏览器与服务器之间的一种默契,如果把浏览器与服务器的交互看成买卖的话,cookie很像会员卡,发卡的是服务器,用卡的是浏览器,浏览器拿到卡之后每次消费都会携带着卡片,直到卡片过期。
服务器发的卡片有两种类型,一次作废的卡,一定期限的卡。如果设置了使用期限就是一定期限的卡,没设置了使用期限就是一次作废的卡。
下面将通过一个小栗子来展示一下cookie的操作
- 点击访问后台API时完成一次异步HTTP请求
- 点击设置cookie时设置名称为visits的cookie值为100
- 点击删除Cookie时,设置名称为visits的cookie值为空,并设置为立即过期
创建cookie
一般来说cookie是由服务器端创建保存在客户端的,不过客户端也可以创建cookie
-
服务器端创建Cookie
服务器端向客户端发送Cookie是通过HTTP响应报文实现的,在Set-Cookie中设置需要向客户端发送的Cookie,Set-Cookie会报包含在响应头中,Set-Cookie响应头是服务器返回的响应头用来在浏览器种Cookie,一旦被种下,当浏览器访问符合条件的url地址时,会自动带上这个cookie。本例中,通过异步HTTP请求调用后端接口来获取cookie
//cookie.php 设置cookie if (!isset($_COOKIE["visits"])) $_COOKIE["visits"] = 0; $visits = $_COOKIE["visits"] + 1; setcookie("visits",$visits,time()+3600); setcookie("name","张三",time()+3600,"/");
第一次访问接口时,在开发者工具的Network面板中,可以看到cookie.php的响应头,这时候请求头中没有携带cookie.
再次访问,请求头中出现了cookie
JS可以通过document.cookie接口可以获取到cookie,获取的的cookie是个字符串(只能获取非 HttpOnly类型的cookie),它包含了当前页的所有cookie,字符串由键值对 key=value构成,键值对之间由一个分号和一个空格隔开。
cookie的内容
一个cookie包含若干个键值对形式的字段。
以Chrome浏览器为例,在开发者工具的Application->Storage->Cookies查看当前域的cookie:
浏览器中的Cookie主要由以下几部分组成:
1、Name:cookie唯一的名称
cookie中不能直接存储中文数据。需要将中文数据转码,传输过程中会自动进行URL编码处理。
2、Value:cookie值
同Name一样会自动进行URL编码处理。
3、Domain:域,表示当前cookie所属于哪个域或子域下面。
如果没有指定Domain的值,那么其Domain的值默认为当前所提交的http的请求所对应的主域名。
4、Path:表示cookie的所属路径。
path默认值为设置该cookie的网页所在的目录,/表示对整个树有效。
Domain和Path加起来构成了 URL,它们共同决定了cookie何时被浏览器自动添加到请求头部中发送出去以及能被哪些 URL 访问。如果没有设置这两个选项,则会使用默认值。
Cookie存储遵循同源策略
,同一站点的不同页面之间是可以互相共享存储数据;不同站点的页面无法互相读取对方存储数据。
如本例中,域192.168.1.177中在路径cookie中的页面发送HTTP请求时将携带2个cookie,其他页面携带一个cookie
5、Expires/Max-Age:表示cookie的有效期。
- expire的值是一个时间,过了这个时间,该cookie就失效了;用max-age指定当前cookie是在多长时间之后失效。同时设置了expire和max-age,max-age优先。
- 如果cookie没有指定有效期,那么cookie会被
临时存储保存在内存中
,此cookie有效期只是当前的session,即是session cookie,当前session会话结束后,即为过期,当关闭该页面的时候,此cookie就会被浏览器删除。 - 如果cookie没有设置有效期,设置了有效期会被保存在客户端的硬盘中,当有效期限过了会被自动删除,
JS就是通过设置cookie的有效期来删除cookie
的。
6、Secure:表示该cookie只能用https传输。
一般用于包含认证信息的cookie,要求传输此cookie的时候,必须用https传输。
7、Httponly:表示此cookie是否能通过 js 去访问
这种类型的cookie只能通过服务端来设置,在客户端是不能通过js代码去设置一个httpOnly类型的cookie的
前端操作Cookie
在这个例子中,我们是通过服务端创建了一个cookie,实际上前端也可以一厢情愿的创建cookie,创建好的cookie会通过HTTP请求发送个后端,虽然这样做没什么意义。
在网上我找到一个封装的很好的前端操作Cookie的方法,直接拿来用
var CookieUtil = {
// 获取cookie
get: function (name) {
var cookieName = encodeURIComponent(name) + "=",
cookieStart = document.cookie.indexOf(cookieName),
cookieValue = "";
if (cookieStart > -1) {
var cookieEnd = document.cookie.indexOf(";", cookieStart);
if (cookieEnd == -1) {
cookieEnd = document.cookie.length;
}
cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
}
return cookieValue;
},
// 设置cookie
set: function (name, value, expires, domain, path, secure) {
var cookieText = "";
cookieText += encodeURIComponent(name) + "=" + encodeURIComponent(value);
if (expires instanceof Date) {
cookieText += "; expires=" + expires.toGMTString();
}
if (path) {
cookieText += "; path=" + path;
}
if (domain) {
cookieText += "; domain=" + domain;
}
if (secure) {
cookieText += "; secure";
}
document.cookie = cookieText;
},
// 删除cookie
unset: function (name, domain, path, secure) {
this.set(name, "", Date(0), domain, path, secure);
}
};
//获取Cookie
CookieUtil.get('visits') //"2"
CookieUtil.get('name') //"张三"
//设置Cookie
CookieUtil.set('visits','100')
//删除Cookie
CookieUtil.unset('visits');
cookie被删除后,在浏览器中查看,它的有效期变成了Session,当关闭浏览器后这条cookie将被删除
总结
-
前端不要创建cookie
前端有可能会因为某种需求创建cookie,这些cookie也会被携带着发给服务器,而服务器并不会理会,等于浪费了带宽,所以尽量改用其他的本地存储方案,如:localStorage和sessionStorage。 -
不要使用cookie来存储一些隐私数据,以防隐私泄露
-
我们可以在浏览器上保存任何文本,而且我们还可以随时随地的去阻止它或者删除。我们同样也可以禁用或者编辑cookie,但是有一点需要注意不要使用cookie来存储一些隐私数据,以防隐私泄露。
-
添加与覆盖:
浏览器用cookie名称来区别cookie,添加不同名称cookie会一直续在前一个cookie后,同名的cookie会覆盖值。 -
删除cookie: 不能直接删除cookie,但是设置过期日期为过去,浏览器会删除cookie。
-
中文及特殊字符支持:
使用encodeURIComponent()函数编码cookie值,读取时使用decodeURIComponent()函数解码。
在Chrome浏览器中查看Cookie,chrome://settings/siteData,在这里可以有针对性的删除cookie