简述cookie 、localStorage和sessionStorage

Web Storage规范

是HTML5的一部分

目的:克服由cookie带来的一些限制,当数据需要被严格的控制在客户端时,无须持续的将数据发回服务器。

目标

  • 提供一种cookie之外的存储会话数据的途径
  • 提供一种存储大量可以跨session存在的数据的机制

定义
Web Storage规范包含两种对象的定义:sessionStorage和globalStorage**。这两个对象在支持的浏览器中都是以 window 对象属性 的形式存在的。
注意:在使用之前记得查看其浏览器支持情况

Storage类型

Storage类型的方法:

  • clear(): 删除所有值
  • getItem(name): 根据指定的名字 name 获取对应的值
  • setItem(name, value): 为指定的name设置一个对应的值
  • key(index):获得index位置处的值的名字。
  • removeItem(name):删除name指定的键值对。
    还可以通过length属性来判断有多少键值对存放在Storage对象中

注意: Storage类型只能存储字符串。非字符串的数据在存储之前会被转换为字符串

sessionStorage对象

sessionStorage 对象是存储特定于某个会话的数据,当页面被重新加载时其仍然存在,只有当浏览器被关闭或者当前页面被关闭时,数据才会被清除;可以理解为数据被存储在浏览器中,只有浏览器被关闭后,数据才会被清除,同时,如果浏览器支持,在浏览器崩溃并重启之后仍然可以访问存储与sessionStorage中的数据

因为sessionStorage对象绑定于某个服务器会话,所以当文件在本地运行的时候是不可用的。

存储在sessionStorage中的数据只能由最初给对象存储数据的页面访问到,其只针对于当前会话,所以对多页面应用有限制

使用
sessionStorage对象是Storage的一个实例,所以可以使用setItem()或者直接设置新的属性存储数据
如:

// 使用方法存储数据
sessionStorage.setItem('name', 'Hexon');
// 使用属性存储数据
sessionStorage.book = 'Professional Javascript'; 

// 使用方法读取数据
var name = sessionStorage.getItem('name');
// 使用方法读取数据
var book = sessionStorage.book;

// 通过key来迭代存储与sessionStorage中的键值
for (var i = 0, len = sessionStorage.length; i < len; i++) {
  var key = sessionStorage.key(i);
  var value = sessionStorage.getItem(key);
  alert(key + '=' + value);
}

// 使用for-in循环迭代sessionStorage中的值
for (var key in sessionStorage) {
  val value = sessionstorage.getItem(key);
  alert(key + '=' + value);

不同的浏览器写入数据方面略有不同,FireFox和WebKit实现了同步写入,所以添加到存储空间中的数据是立刻被提交的。而IE的实现是异步写入数据,在设置数据和将数据写入磁盘之间可能有延迟

总结:sessionStorage对象应该只用于针对会话小段数据存储。如果需要跨会话存储数据,那么localStorage或者globalStorage更合适

globalStorage对象

只用FireFox2中实现了globalStorage对象,主要目的是为了实现 跨会话存储数据,但有特定的访问限制。

要使用globalStorage,首先要指定哪些域名可以访问该数据

使用方法

// 只针对 域名 wrox.com 的存储访问
globalStorage['wrox.com'].name = 'hexon';
var name = globaleStorage['wrox.com'].name;

注意:

  • globalStorage对象不是Storage的实例,而具体的globalStorage['wrox.com'] 才是
  • 当使用 globalStorage[''].name = 'hexon'来存储数据时,表示任何人都可以访问,一定不要这样做,不安全
  • 对globalStorage空间的访问,是依据发起请求的页面的域名、协议和端口 来限制的;如使用https协议在wrox.com中存储了数据,那么通过http访问的wrox.com的页面将无法访问该数据
  • 如果事先无法确定域名,那么使用 location.host 作为属性名比较安全,表示页面必须来自于同一个域名、协议和端口,才可以访问
  • 如果不使用removeItem() 或者 delete 删除,或者用户未清除浏览器缓存,存储在globalStorage属性中的数据将会一直保存在磁盘上

注意: globalStorage对象在修订过的HTML5规范中被localStorage对象所取代

localStorage 对象

localStorage对象在修订过的HTML5规范中作为持久保存客户端数据的方案取代了globalStorage

与globalStorage不同,不能给localStorage指定规则,规则在HTML5规范中就被制定,要访问同一个localStorage对象,页面必须来自同一个域名(子域名无效)、同一种协议,在同一端口上,这相当于 globalStorage[location.host]

localStorage是Storage类型的实例,因此可以像使用sessionStorage一样使用它

同时, 为了兼容只支持globalStorage对象的浏览器,可以使用以下方式进行能力检测:

function getLocalStorage() {
  if (tpyeof localStorage === 'object') {
     return localStorage;
  } else if (typeof globalStorage === 'object') {
     return globalStorage[location.host];
  }  else {
     throw new Error('Local Storage not available.');
  }
}

sessionStorage和localStorage的对比与使用

概念

这两者都是本地存储,均不会被发送到服务器端,其主要在生命周期上有比较明显的区别;localStorage的生命周期更长,没有过期时间,原则上要等到通过JavaScript将内容清除掉或者清空cookie时才会消失;而sessionStorage则在Browser或Tab被关闭时就会清空

限制

  • 对于localStorage而言,大多数桌面浏览器会设置每个来源5MB的限制,具体依浏览器而异
  • 对于sessionStorage,也因浏览器而异,一般每个来源在2.5MB ~ 5MB 之间

浏览器支持情况
这两者都都需要浏览器的API支持,浏览器的支持情况如下:

image.png

使用
通过window.localStoragewindow.sessionStorage这而两个对象进行操作

以操作localStorage为例:

  • 从存储中获取值
    window.localStorage.getItem('key')
function setStyles() {
  var currentColor = localStorage.getItem('bgcolor');
  var currentFont = localStorage.getItem('font');
  var currentImage = localStorage.getItem('image');

  document.getElementById('bgcolor').value = currentColor;
  document.getElementById('font').value = currentFont;
  document.getElementById('image').value = currentImage;

  htmlElem.style.backgroundColor = '#' + currentColor;
  pElem.style.fontFamily = currentFont;
  imgElem.setAttribute('src', currentImage);
}
  • 在存储中设置值
    window.localStorage.setItem可以从存储中获取指定的数据项或者设置新的数据项,该方法接受两个参数——要创建/修改的数据项的键,和对应的值。
function populateStorage() {
  localStorage.setItem('bgcolor', document.getElementById('bgcolor').value);
  localStorage.setItem('font', document.getElementById('font').value);
  localStorage.setItem('image', document.getElementById('image').value);
  setStyles();
}
  • 通过 StorageEvent 响应存储的变化
    无论何时,storage对象发生变化时(即创建/更新/删除,重复设置相同的项不会触发,storage.clear()方法至多触发一次),都会触发StorageEvent事件
    window.addEventListener('storage', function(){});
    示例:
window.addEventListener('storage', function(e) {  
  document.querySelector('.my-key').textContent = e.key;
  document.querySelector('.my-old').textContent = e.oldValue;
  document.querySelector('.my-new').textContent = e.newValue;
  document.querySelector('.my-url').textContent = e.url;
  document.querySelector('.my-storage').textContent = e.storageArea;
});

注意:在同一个页面内发生的改变不会起作用——在相同域名下的其他页面(如一个新标签或 iframe)发生的改变才会起作用。在其他域名下的页面不能访问相同的 Storage 对象。

  • 删除数据记录
    window.localStorage.removeItem():接收一个参数,要删除的数据项key值
    window.localStorage.clear():不接收参数,只是简单的清空域名对应的整个存储数据

cookie

起源: 最初由网景公司引入,用于在客户端存储回话信息

工作方式:要求服务器对任意HTTP请求,在响应头中添加Set-Cookie 字段来设置cookie,在客户端接收到这个cookie信息之后,将其存储起来,在此之后,当客户端再给创建它的域名发送HTTP请求时,都会在HTTP头中添加cookie信息,服务器可以根据这个cookie信息来决定该用户可以执行哪些操作(例如:是否允许它进行访问)

cookie的组成:
cookie由浏览器保存在客户端计算机中,由以下几块信息组成:

  • 名称:cookie的名称,这是唯一的,且字符不区分大小写。注意:cookie的名称必须是经过URL编码的
  • :存储在cookie中的字符串值。注意:值必须经过URL编码
  • :cookie对于哪个域有效,所有向该域发送的请求中,都会包含这个cookie信息,如果没有设置,则这个域会被认作是设置cookie的那个域
  • 路径:对于域下的路径访问,会包含cookie信息
  • 失效时间
  • 安全标志

一个服务器发给客户端的SetCookie信息,如下:

HTTP/1.1 200 OK
Content-type: text/html
Set-cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT; domain=.wrox.com; path=/; secure
Other-header: other-header-value

Set-cookie: name=value; expires=Mon, 22-Jan-07 07:10:24 GMT domain=.wrox.com; path=/; secure
这个Set-cookie的解释如下:

  • cookie名称: name
  • cookie的值:value (注意:值跟名称是不同的东西)
  • 失效时间:Mon, 22-Jan-07 07:10:24 GMT;(这是GMT时间)
  • 域名: .wrox.com
  • 路径: /
  • 安全标志: secure(只有当客户端通过SSH连接时,才可以传输该cookie)

cookie的特点

  • 创建方式:是由服务器来创建 cookie 信息的
  • 存放位置:客户端接收到服务器的cookie信息之后,将其存放在客户端的计算机中
  • cookie个数限制:cookie是绑定在域名下的,因此每个域的cookie个数是有限的,不同浏览器的限制不同,一般为50个,chrome和safari没有硬性限制。
  • cookie尺寸限制:对于每个域下的cookie的尺寸限制为4K字节注意:是一个域下的所有cookie的总尺寸之和要小于4K字节,不是单个cookie的尺寸
  • 失效时间:默认情况下,浏览器会话结束时即将所有的cookie删除,但是,可以自己设置失效时间,当未到达失效时间时,cookie将一直保存在客户端计算机中,除非自己手动删除
  • cookie会被附加在每个http请求中,因此会增加流量
  • 安全标志:当指定后(通过Set-Cookie中添加 secure 关键字即可),cookie只有在使用SSL连接的时候才发送到服务器

注意事项

  • cookie个数和尺寸的限制,超过限制后,不同的浏览器有不同的处理方式,因此,一定不要超过限制
  • 域、路径、失效时间和secure标志都是服务器给浏览器的指示,以指定何时应该发送cookie,这些参数不会作为发送给服务器cookie信息的一部分
  • cookie的名称是经过URL编码的,注意:是名称
  • Javascipt中处理cookie有些复杂,主要是接口不好用,即:document.cookie

cookie的缺陷

  • cookie会被附加在每个http请求中,因此会无形中增加流量
  • 由于http请求中的cookie是明文传输,因此有安全问题(除非使用https),不要使用cookie存放重要的数据
  • cookie的大小限制是4kb,对于复杂的存储需求可能不够用

cookie的使用

  • 获取cookie:document.cookie,通过该方法可以获取cookie
  • 删除cookie:设置document.cookie并不会覆盖cookie,除非设置的cookie的名称已经存在。那么就会对原cookie进行覆盖
    封装的cookie代码
let CookieUtil = {
    get: (name) => {
      let cookieName = encodeURIComponent(name) + "=",
          cookieStart = document.cookie.indexOf(cookieName),
          cookieValue = null;

      if (cookieStart > -1) {
        let cookieEnd = document.cookie.indexOf(';', cookieStart);
        if (cookieEnd === -1) {
          cookieEnd = document.cookie.length;
        }
        cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
      }

      return cookieValue;
    },
    set: function (name, value, expires, path, domain, secure) {
      let 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, 并没有直接的删除cookie的方法,这里通过重新设置cookie名称,来对cookie进行替换
    // 同时 将过期时间expires设置为过去的时间,
    unset: function(name, path, domain, secure) {
      this.set(name, '', new Date(0), path, domain, secure);
    }
  }

浏览器本地存储中 cookie 和 localStorage 有什么区别? localStorage 如何存储删除数据。

sessionStorage、localStorage和cookie 这三者都是用于浏览器端存储数据,而且都是字符串类型的键值对

区别在于:

  • 数据传输方面:在每个http请求中都会附加cookie信息,cookie中的信息能够被推送到服务器端;而sessionStorage和localStorage不会被推送到服务器端
  • 存储大小不同:cookie最大支持4KB,而sessionStorage和localStorage一般在2.5~10MB
  • 生命周期:默认情况下,cookie开始于浏览器启动,结束于浏览器关闭,但是可以手动设置cookie的过期时间,同时,到期后被删除;而对于localStorage,没有过期时间,原则上只要不手动删除,其会一直被保存在本地上,sessionStorage的数据关闭浏览器时清除
  • 被创造的初衷不同:sessionStorage和localStorage都属于WebStorage,创建他们的目的就是用于存储客户端数据;
    而cookie最早在网景的浏览器中被支持,主要目的是为了辨别用户身份而存储在本地终端的数据。

参考:在HTML5的时代,重新认识Cookie


参考:


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,198评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,663评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,985评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,673评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,994评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,399评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,717评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,407评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,112评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,371评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,891评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,255评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,881评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,010评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,764评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,412评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,299评论 2 260

推荐阅读更多精彩内容