HTTP状态管理机制之Cookie(转)

本文详细介绍了Cookie的起源,如何进行Cookie操作,包括名称、值、域名、路径、失效日期、安全标志等内容,并阐述了Cookie的两种类型:普通Cookie和安全性更高的HttpOnly Cookie。文章还讨论了Cookie在实际应用中的常见问题,如如何避免Cookie数量过多导致的页面访问错误,以及在保存中文字符时需要使用Unicode编码。最后,文章指出了Cookie的一些陷阱和注意事项,以帮助开发者更好地理解和使用Cookie。

一、cookie 起源

cookie 最早是网景公司的雇员 Lou Montulli 在1993年3月发明,后被 W3C 采纳,目前 cookie 已经成为标准,所有的主流浏览器如 IE、Chrome、Firefox、Opera 等都支持。

cookie 的诞生是由于 HTTP 协议的天生缺陷,HTTP 是一种无状态的协议,简单的 Request 和 Response 一旦请求/响应结束,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话,即服务器并不清楚是哪个客户端。


一些典型应用如 登陆/购物车 就无法实现了。比如,用户 A 在购物商城购买的商品都应该放在 A 的购物车内,不论是用户 A 什么时间购买的,这都是属于同一个会话的,不能放入用户 B 或用户 C 的购物车内,这不属于同一个会话。

 

基本的原理如图

 

二、cookie 操作

对 cookie 的操作包括如下

  1. 名称(Name)
  2. 值(Value)
  3. 域(Domain)
  4. 路径(Path)
  5. 失效日期(Expires)
  6. 安全标志(Secure)
  7. HttpOnly (仅服务器端)

注意,cookie 多数时候由服务器端创建,JS 也可以创建 cookie,但 HttpOnly 类型的 JS 无法创建。

 

浏览器提供的 cookie API (document.cookie)实在过于简陋,可以稍封装下,如以下采用setter/getter方式 cookie 函数就方便了许多

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/*
  * JS 写cookie和读cookie操作
  *
  * **取cookie**
  *   cookie(name)
  *
  * **写cookie**
  *   cookie(name, value)
  *   cookie(name, value, option)
  */
var  cookie =  function (name, value, option) {
     var  doc = document
     if  (value != undefined) {  // set
         option = option || {}
         if  (value ===  null ) {
             value =  ''
             option.expires = -1
         }
         var  expires =  ''
         if  (option.expires && ( typeof  option.expires ==  'number'  || option.expires.toUTCString)) {
             var  date =  new  Date
             if  ( typeof  option.expires ==  'number' ) {
                 date.setTime(date.getTime() + (option.expires * 24 * 60 * 60 * 1000))
             else  {
                 date = option.expires
             }
             // for IE
             expires =  '; expires='  + date.toUTCString()
         }
         var  path   = option.path ?  '; path='  + option.path :  ''
         var  domain = option.domain ?  '; domain='  + option.domain :  ''
         var  secure = option.secure ?  '; secure'  ''
         doc.cookie = [name,  '=' , encodeURIComponent(value), expires, path, domain, secure].join( '' )
 
     else  // get
         var  cookieValue =  null
         if  (doc.cookie && doc.cookie !=  '' ) {
             var  cookies = doc.cookie.split( ';' )
             for  ( var  i = 0; i < cookies.length; i++) {
                 var  cookie = $.trim(cookies[i]).split( '=' )
                 if  ( cookie[0] == name && cookie.length > 1 ) {
                     try  {
                         cookieValue = decodeURIComponent(cookie[1])
                     catch (e) {
                         cookieValue = cookie[1]
                     }
                     break
                 }
             }
         }
         return  cookieValue
     }
};

当然,还有更方便的 https://github.com/florian/cookie.js,提供了更多便捷函数。

  

三、cookie 类型

  1. 普通 cookie,服务器端和 JS 都可以创建,JS 可以访问
  2. HttpOnly cookie,只能由服务端创建,JS 是无法读取的,主要基于安全考虑
  3. 安全的 cookie (仅https),服务器端和 JS 都可以创建,JS 仅HTTPS下访问

 

比如,在新浪云上测试页面:http://snandy.sinaapp.com/php/cookie.php,我种了 3 个 cookie,分别是 c1, c2, c3

1
2
3
4
5
6
7
8
9
$d1  mktime (1,1,1,1,1,2018);
// 普通cookie
setcookie( "c1" "Jack" $d1 );
 
// 安全的cookie,仅https,第6个参数
setcookie( "c2" "John" $d1 , NULL, NULL, TRUE);
 
// HttpOnly cookie 第7个参数
setcookie( "c3" "Resig" $d1 , NULL, NULL, NULL, TRUE);

用 Firefox 访问

我种的三个都有,saeut是新浪云种的。

 

在 firebug 控制台输入 document.cookie

可以看到,c2,c3 都是访问不到的。c2 是 安全的cookie,需要在https协议下访问,c3 则是 httpOnly 的,JS无法访问,这个需要注意。

 

把访问协议改成 https: https://snandy.sinaapp.com/php/cookie.php,firebug 切换到控制台再输入 document.cookie,可以看到 c2 就可以访问了

 

四、cookie 的坑

1. Cookie 太大或数量过多时页面访问报错,比如会出现如下提示

因此站点的 cookie 需要管理,不能随意种 cookie。另外尽量指定path,将cookie限定在指定范围内。

 

网站 browsercookielimits.squawky.net ,记录了各浏览器 cookie 大小

 

2. 保存中文时需要Unicode编码(encodeURIComponent),否则存的是乱码

http://www.cnblogs.com/snandy/p/5121293.html

转载于:https://www.cnblogs.com/softidea/p/5129828.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值