转载,原文地址 https://segmentfault.com/a/1190000004743454

一、引言

随着浏览器的处理能力不断增强,越来越多的网站开始考虑将数据存储在「客户端」,那就不得不谈谈本地存储了。本地存储的好处显而易见,一是避免取回数据前页面一片空白,如果不需要最新数据也可以减少向服务端请求的次数,从而减少用户等待从服务器获取数据的时间,二是网络状态不佳时仍可以显示离线数据。

下面来看看常用的本地存储。

chrome浏览器打开一个网页,进入开发者模式,点击Resources,我们可以看到:

以上的 indexedDBLocal StorageSession StorageCookies,就是常用的本地存储其中几种。下面我们一一了解。

二、常用的本地存储

1、cookie

HTTP cookie,通常直接叫做cookie,是客户端用来存储数据的一种选项,它既可以在客户端设置也可以在服务器端设置。cookie会跟随任意HTTP请求一起发送。

优点:兼容性好

缺点:一是增加了网络流量;二则是它的数据容量有限,最多只能存储4KB的数据,浏览器之间各有不同;三是不安全。

2、userData

userData是微软通过一个自定义行为引入的持久化用户数据的概念。用户数据允许每个文档最多128KB数据,每个域名最多1MB数据。

缺点:userData不是 web 标准的一部分,只有IE支持

3、web存储机制

web storage,包括两种:sessionStorage 和 localStorage,前者严格用于一个浏览器会话中存储数据,因为数据在浏览器关闭后会立即删除;后者则用于跨会话持久化地存储数据。

缺点:IE不支持 SessionStorage,低版本IE ( IE6, IE7 ) 不支持 LocalStorage,并且不支持查询语言

4、indexedDB

indexed Database API,简称为indexedDB,是在浏览器中保存结构化数据的一种「数据库」。它类似SQL数据库的结构化数据存储机制,代替了废弃已久的web SQL Database API,它能够在客户端存储大量的结构化数据,并且使用索引高效检索的API。

缺点:兼容性不好,未得到大部分浏览器的支持。

5、Flash cookie

Flash本地存储,类似于HTTP cookie,它是利用 SharedObject类来实现本地存储信息。它默认允许每个站点存储不超过100K的数据,远大于cookie,而且能够跨浏览器。

缺点:浏览器需安装 Flash 控件,毕竟它是通过Flash的类来存储。所幸的是,没有安装Flash的用户极少。

6、Google Gears

Google Gears是Google在07年发布的一个开源浏览器插件,Gears 内置了一个基于SQLite的嵌入式 SQL数据库,并提供了统一API 对 数据库进行访问,在取得用户授权之后,每个站点可以在SQL数据库中存储「不限大小」的数据。

缺点:需要安装 Google Gears 组件

下面将对 cookie 进行详细的介绍。

三、cookie的用途

3.1 概述

下面来详细谈谈cookie。

Cookie是一小段文本信息,伴随着用户请求在 Web 服务器和浏览器之间传递。它存储于访问者的计算机中,每当同一台计算机通过浏览器请求某个页面时,就会发送这个 cookie。

首先声明,它是「浏览器」提供的一种机制,它将 document 对象的 cookie 属性提供给 JavaScript。可以使用JavaScript来创建和取回 cookie 的值,因此我们可以通过document.cookie访问它。

cookie是存于用户硬盘的一个文件,这个文件通常对应于一个域名,也就是说,cookie可以跨越一个域名下的多个网页,但不能跨越多个域名使用。

3.2 cookie的用途及工作原理

那cookie具体能干什么呢?

cookie 将信息存储于用户硬盘,因此可以作为全局变量,这是它最大的一个优点。它最根本的用途是 Cookie 能够帮助 Web 站点保存有关访问者的信息,以下列举cookie的几种小用途。

  • 保存用户登录信息。这应该是最常用的了。当您访问一个需要登录的界面,例如微博、百度及一些论坛,在登录过后一般都会有类似"下次自动登录"的选项,勾选过后下次就不需要重复验证。这种就可以通过cookie保存用户的id。

  • 创建购物车。购物网站通常把已选物品保存在cookie中,这样可以实现不同页面之间数据的同步(同一个域名下是可以共享cookie的),同时在提交订单的时候又会把这些cookie传到后台。

  • 跟踪用户行为。例如百度联盟会通过cookie记录用户的偏好信息,然后向用户推荐个性化推广信息,所以浏览其他网页的时候经常会发现旁边的小广告都是自己最近百度搜过的东西。这是可以禁用的,这也是cookie的缺点之一。

那么,cookie是怎么起作用的呢?

在上一节中我们知道 cookie 是存在用户硬盘中,用户每次访问站点时,Web应用程序都可以读取 Cookie 包含的信息。当用户再次访问这个站点时,浏览器就会在本地硬盘上查找与该 URL 相关联的 Cookie。如果该 Cookie 存在,浏览器就将它添加到request headerCookie字段中,与http请求一起发送到该站点。

要注意的是,添加到 request header 中是「浏览器的行为」,存储在cookie的数据「每次」都会被浏览器「自动」放在http请求中。因此,如果这些数据不是每次都要发给服务器的话,这样做无疑会增加网络流量,这也是cookie的缺点之一。为了避免这点,我们必须考虑什么样的数据才应该放在cookie中,而不是滥用cookie。每次请求都需要携带的信息,最典型的就是身份验证了,其他的大多信息都不适合放在cookie中。

四、cookie的格式

明白了工作原理后,接着我们来看看cookie长什么样,然后再一步步深入了解该怎么去用它。

那么,如何获取 cookie 呢?从第1小节了解到,浏览器提供了 cookie 属性给 JavaScript,因此可以通过 document.cookie 来访问这个页面中的cookie。

这是一串字符串,仔细观察,我们可以发现规律。每个 cookie 都以名/值对的形式,即 name=value,名称和值都必须是URL编码的,且两对cookie间以分号和空格隔开。(ps:千万不要忘了空格,特别是在获取某个 cookie 时)

依旧是进入开发者模式,我们来看下Resources下的Cookies

红色标注的那行,稍微猜想一下,也可以知道它是与cookie相关的值和属性。name、value 不必多说,自然是 cookie 的名和值。domainPathExpries/Max-agehttponly(即HTTP选项)、Secure 等均是 cookie 的属性,我们一一了解下。

我们先手动添加几个cookie,然后再来一一看下属性(具体设置cookie的方法在下一小节详解)。

代码如下:

document.cookie = "test1=myCookie1;"
document.cookie = "test2=myCookie2; domain=.google.com.hk; path=/webhp"
document.cookie = "test3=myCookie3; domain=.google.com.hk; expires=Sat, 04 Nov 2017 16:00:00 GMT; secure"
document.cookie = "test4=myCookie4; domain=.google.com.hk; max-age=10800;"

4.1 domain和path

domain 和 path 这两个选项共同决定了cookie能被哪些页面共享。

标红区域是默认情况,正如例1中未设置domain和path最终显示的情况。

domain 参数是用来控制 cookie对「哪个域」有效,默认为设置 cookie的那个域。这个值可以包含子域,也可以不包含它。如上图的例子,Domain选项中,可以是".google.com.hk"(不包含子域,表示它对google.com.hk的所有子域都有效),也可以是"www.google.com.hk"(包含子域)。

path用来控制cookie发送的指定域的「路径」,默认为"/",表示指定域下的所有路径都能访问。它是在域名的基础下,指定可以访问的路径。例如cookie设置为"domain=.google.com.hk; path=/webhp",那么只有".google.com.hk/webhp"及"/webhp"下的任一子目录如"/webhp/aaa"或"/webhp/bbb"会发送cookie信息,而".google.com.hk"就不会发送,即使它们来自同一个域。

4.2 expries/max-age失效时间

expries 和 max-age 是用来决定cookie的生命周期的,也就是cookie何时会被删除。

标红区域为默认情况,即Session,表示浏览器会话结束时(即关闭浏览器)就会删除cookie。

当然,用户也可以通过expries设置删除时间。这个值是个GMT格式的日期,类似例三中的Sat, 04 Nov 2017 16:00:00 GMT,这表明这个 cookie 将在2017-11-04的16时整失效,在此期间浏览器关闭后此cookie仍会保存在用户的机器中。GMT格式可以通过toGMTString() 和 toUTCString() 获得。如果设置的失效时间是个以前的时间,则 cookie 会被立即删除,这也是用来删除 cookie 的方法。

在新的http协议中已经使用 max-age 属性来取代 expries。expries 表示的是失效时间,准确讲是「时刻」,max-age表示的是生效的「时间段」,以「秒」为单位。若 max-age 为正值,则表示 cookie 会在 max-age 秒后失效。如例四中设置"max-age=10800;",也就是生效时间是3个小时,那么 cookie 将在三小时后失效。若 max-age 为负值,则cookie将在浏览器会话结束后失效,即 session,max-age的默认值为-1。若 max-age 为0,则表示删除cookie。

4.3 secure

secure是 cookie 的安全标志,通过cookie直接包含一个secure单词来指定,也是cookie中唯一一个非名值对儿的部分。指定后,cookie只有在使用SSL连接(如HTTPS请求)时才会发送到服务器。

默认情况为空,不指定 secure 选项,即不论是 http 请求还是 https 请求,均会发送cookie。

标红区域为指定 secure 后的情况,同时也说明指定 secure 后 cookie 仍可见。

注意:只有保证网页是https协议(或其他安全协议)请求的,才能客户端在客户端通过 js 去设置secure 类型的 cookie。

4.4 httponly

httponly属性是用来限制客户端脚本对cookie的访问。将 cookie 设置成 httponly 可以减轻xss攻击的危害,防止cookie被窃取,以增强cookie的安全性。(由于cookie中可能存放身份验证信息,放在cookie中容易泄露)

HTTP那列用来表示是否设置了httponly属性,若设置了httponly,则会打勾(即标红区域)

我们用 js 获取下cookie,可以发现访问不到 NID 这个cookie,说明js是无法读取和修改 httponly cookies,当然也不能设置 cookie 为 httponly,这只能通过服务器端去设置。

默认情况是不指定 httponly,即可以通过 js 去访问。

五、设置cookie

将 cookie 的属性介绍后,下一步就该谈谈如何利用这些属性去设置 cookie 了~

5.1 服务器端设置

服务器通过发送一个名为 Set-Cookie 的HTTP头来创建一个cookie,作为 Response Headers 的一部分。如下图所示,每个Set-Cookie 表示一个 cookie(如果有多个cookie,需写多个Set-Cookie),每个属性也是以名/值对的形式(除了secure),属性间以分号加空格隔开。格式如下:

Set-Cookie: name=value[; expires=GMTDate][; domain=domain][; path=path][; secure]

只有cookie的名字和值是必需的。

注意,通过 Set-Cookie 指定的可选项(域、路径、失效时间、secure标志)只会在「浏览器端」使用,它们都是服务器给浏览器的指示,以指定何时应该发送cookie。这些参数不会被发送至服务器端,只有name和value才会被发送。

5.2 客户端设置

客户端设置cookie的格式和Set-Cookie头中使用的格式一样。如下:

document.cookie = "name=value[; expires=GMTDate][; domain=domain][; path=path][; secure]"

可以参照第3小节的四个例子测试下。

document.cookie = "test1=myCookie1;"
document.cookie = "test2=myCookie2; domain=.google.com.hk; path=/webhp"
document.cookie = "test3=myCookie3; domain=.google.com.hk; expires=Sat, 04 Nov 2017 16:00:00 GMT; secure"
document.cookie = "test4=myCookie4; domain=.google.com.hk; max-age=10800;"

若想要添加多个cookie,只能重复执行 document.cookie(如上)。这可能和平时写的 js 不太一样,一般重复赋值是会覆盖的,但对于cookie,重复执行 document.cookie 并「不覆盖」,而是「添加」(针对「不同名」的)。

5.3 cookie的修改

上一节的最后是否有些疑惑?针对不同名的cookie,执行document.cookie是添加,那「同名」的呢?实地演练一下~

如下图,我们以test1作为实例试验下。

再执行次 document.cookie = "test1=newCookie;"

我们发现,原来值为myCookie1的cookie不见了,test1原来的值myCookie1newCookie覆盖了,这也是这章要讲解的,修改cookie的方法。还没结束哦,我们再试下能不能修改参数。

document.cookie = "test1=newCookie; max-age=3600; secure"

如上图,我们成功更改了名为test1的cookie的过期时间及安全标志。

document.cookie = "test1=newCookie; domain=.google.com.hk; max-age=3600; secure"
document.cookie = "test1=newCookie; path=/webhp; max-age=3600; secure"

我们发现没有覆盖原来的cookie,而是新增了cookie。这也是修改cookie时需要注意的地方,可以修改原cookie的expries、secure属性,但不能修改domain、path属性。修改cookie时domain、path必须与原cookie保持一致。

5.4 cookie的删除

cookie的删除其实特别简单,也是对此cookie重新赋值,上面介绍expriesmax-age时也有提到,将expries设为一个过去的时间或将max-age设为0,都可以删除cookie。同时也要特别注意此cookie的domain、path要与原来保持一致。

六、cookie编码

若 cookie 的名或值中包含分号、逗号和空格这三个特殊字符,那么它需要经过URL编码。一般可以使用encodeURIComponent进行编码,它对应的解码函数是decodeURIComponent。若要给 cookie 指定额外的信息,只要将参数追加到该字符串(如下例)。

document.cookie = encodeURIComponent("test") + "=" + encodeURIComponent("myCookie") + "; max-age=3600";

七、cookie的缺点

  • 安全性:由于cookie在HTTP中是明文传递的,其中包含的数据都可以被他人访问,可能会被篡改、盗用。

  • 大小限制:cookie的大小限制在4KB左右,若要做大量存储显然不是理想的选择。

  • 增加流量:cookie每次请求都会被自动添加到Request Header中,无形中增加了流量。cookie信息越大,对服务器请求的时间也越长。

因此要慎用cookie,不要在cookie中存储重要和敏感的数据。

cookie(2)的更多相关文章

  1. Asp.Net MVC 中的 Cookie(译)

    Asp.Net MVC 中的 Cookie(译) Cookie Cookie是请求服务器或访问Web页面时携带的一个小的文本信息. Cookie为Web应用程序中提供了一种存储特定用户信息的方法.Co ...

  2. session & cookie(li)

    Session & Cookie 一.定义 Session,用户在浏览某个网站时,从进入网站到浏览器关闭所经过的这段时间,也就是用户浏览这个网站所花费的时间.Cookie,由服务器端生成,发送 ...

  3. ASP.NET Cookie(一)--基本应用

    Cookie提供了一种在Web应用程序中存储用户特定信息的方法.例如,当用户访问您的站点时,您可以使用Cookie存储用户首选项或其他信息.当该用户再次访问您的网站时,应用程序便可以检索以前存储的信息 ...

  4. springMVC源码分析--国际化实现Session和Cookie(二)

    上一篇博客springMVC源码分析--国际化LocaleResolver(一)中我们介绍了springMVC提供的国际化的解决方案,接下来我们根据springMVC提供的解决方案来简单的实现一个多语 ...

  5. 企业项目开发--cookie(3)

    此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 2.2.3.AdminController   1 package com.xxx.web.admin;   ...

  6. 企业项目开发--cookie(1)

    此文已由作者赵计刚授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. 注:本章代码基于<第五章 企业项目开发--mybatis注解与xml并用>的代码,链接如下: h ...

  7. 细说Cookie(转)

    原文地址:http://www.cnblogs.com/fish-li/archive/2011/07/03/2096903.html#undefined Cookie虽然是个很简单的东西,但它又是W ...

  8. 允许跨域资源共享(CORS)携带 Cookie (转载)

    如何让CORS携带Cookie CORS 是一个 W3C 标准,全称是“跨域资源共享”(Cross-origin resource sharing).默认浏览器为了安全,遵循“同源策略”,不允许 Aj ...

  9. HTTP协议 (七) Cookie(转)

    add by zhj: 客户端通过request header:cookie将cookie发给服务端,而服务端通过response header: set-cookie将cookie传回客户端 一条c ...

随机推荐

  1. html09

    1.Jquery的常用方法1)选择器2)操作节点以下的 obj 都是指 jQuery对象 1.操作样式 obj.css() :不加参数是获取节点的css样式 obj.css({"属性&quo ...

  2. 大神的博客地址liferay

    http://www.huqiwen.com/category/technology-share/liferay/

  3. rpgmakermv插件(1)screenfull.js与Fullscreen.js

    本文分析游戏的全屏化处理. 引入:玩家在不同情景下可能会选择全屏游戏或窗口化游戏,所以作为开发者,应该在设置中加入全屏与否的选项. 两种插件:screenfull.js与Fullscreen.js 1 ...

  4. 奋斗史-IT女生是怎样炼成的

    IT女生的奋斗史 终于来到了毕业季,感觉有点伤感! 记得11年来到大学的时候,还是那么懵懂,什么都不懂,几乎连电脑的基本操作都不会!自己小时候虽然家里穷,但是从小就觉得“软件”是个很神奇的东西,很了不 ...

  5. zookeeper 详解

    是 分布式 协调 服务. ZK的工作:注册:所有节点向ZK争抢注册,注册成功会建立一套节点目录树,先注册的节点为Active节点,后注册节点成为standby;监听事件:节点在ZK集群里注册监听动作: ...

  6. linux常用命令:ip 命令

    ip命令是Linux下较新的功能强大的网络配置工具. 1.命令格式: ip  [OPTIONS]  OBJECT  [COMMAND [ARGUMENTS]] 2.命令功能: ip命令用来显示或操纵L ...

  7. JCTools, 场景特化的并发工具

    同上一篇一样,在jmap -histo中发现MpscChunkedArrayQueue类的实例比较多,javadoc看了下,其原来是出自JC Tools,https://github.com/JCTo ...

  8. Ubuntu下使用face_recognition进行人脸识别

    Face Recognition是一个基于Python的人脸识别库,在github上地址如下:https://github.com/ageitgey/face_recognition. 看着挺好玩,本 ...

  9. 《网络攻防》实验九:web安全基础实践

    本次实验在XX同学的指导下完成 1.实验后回答问题 (1)SQL注入攻击原理,如何防御 SQL注入攻击的基本原理,是从客户端合法接口提交特殊的非法代码,让其注入到服务器端执行业务的SQL中去,进而改变 ...

  10. 20145213《网络对抗》逆向及Bof基础

    实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 该程序同时包含另一个代码片段,getShe ...