客户端存储,那些你知道的和不知道的?

网页的安全和隐私

自从有了动态网页以来,在网页中进行注册登录已经成为了动态网页的标配。与此同时,人们也在不断改善和优化网页,以带给用户更好的浏览效果。很自然的,人们在登录页面也做了很多优化,比如客户端校验,客户端导航提示。由于浏览器无法对用户的操作做任何限制,人们可以随时打开,随手关闭,当人们多次访问同一个网页时,难免会出现反复登录的情况,这时候人们希望有一种记忆功能,能够记忆之前输入过的账户或密码,避免人们反复输入。早先的做法是将账户密码写入硬盘,可以反复读取,但是硬盘是一个公共区域,任何程序都可以读取,这极不安全。虽然用户愿意将个人信息在网页上进行填写,但不表示他们愿意将这些信息永久地保存在硬盘,但有人就这么做了,最终导致了一些用户直接禁用本地存储功能。本文讨论一些更为安全的本地存储以提升用户体验,尽管如此,对于这些本地存储也不能滥用,一旦滥用,同样有遭到禁用的风险。

Web存储

这是一个新概念,随HTML5标准提出来的,后来又从HTML5中分离出来成为一个独立的标准。目前客户端的实现主要包含在localStorage和sessionStorage对象中。目前所有主流浏览器都支持该实现,早期浏览器不支持。localStorage和sessionStorage是持久化关联数组,是名值对映射表,支持大容量数据存储。和使用普通的JavaScript对象没有什么区别。localStorage和sessionStorage的区别是存储的有效期和作用域不同。关于它们的使用,请参考下面的代码片段:

var name = localStorage.username;
name = localStorage["username"];
if(!name){
    name = prompt("What is your name?");
    localStorage.username = name;
}
for(var name in localStorage)
{
    var value = localStorage[name];
}

标准规定,Web存储不仅可以存储原始类型的数据,也可以存储对象和数组,还可以存储日期,正则,甚至文件对象等内置类型的数据。

Web存储的有效期和作用域

localStorage的有效期是永久,除非是程序对数据进行了删除,否则数据永不过期。localStorage的作用域受同源策略影响,同源的网页之间可以共享localStorage,可以相互读取对方的数据,也可以修改和覆盖对方的数据,非同源网页之间则不行。同源策略指的是协议,域名,端口号相同的网页之间可以相互访问对方的数据。另外一点需要注意,localStorage也受浏览器的影响,比如说,firefox的存储的数据可能在Ie上就访问不到。sessionStorage的有效期是当前页面,一旦页面关闭,数据也被清除。sessionStorage的作用域同样受同源策略影响,只有同源网页才能共享数据,并且网页还必须在一个窗口中,也就是说,只有处于一个窗口中的两个iframe才能共享数据。不同窗口的同源网页也不能共享数据。

Web存储API

localStorage和sessionStorage的使用方式非常相似。以localStorage为例,下面的的代码对sessionStorage同样适用。

localStorage.setItem("x", 1);//存储一个数值
localStorage.getItem("x");//获取数值

//枚举所有名/值对
for(var i = 0; i < localStorage.length; i++)
{
    var name = localStorage.key(i);
    var value = localStorage.getItem(name);
}

localStorage.removeItem("x");//删除一项
localStorage.clear();//删除所有

上述代码中有一个值得探讨的地方是,localStorage的存储我们为何不写成localStorage.x = 1?这样似乎更简洁明了。取值的时候直接localStorage.x,这样书写岂不是更简单?的确是更简单。但是标准规定存储对象只能存储数据的副本,程序对数据的改变不能影响存储对象。以下面的代码为例:

localStorage.o = {x:1};
localStorage.o.x = 2;
localStorage.o.x;

如果我们在程序中使用这样的代码,那么我们每次修改数据都直接影响了存储数据,这显然是和标准冲突,也不符合我们日常的需求,用户通常都是在所有信息填写完成后,一次性存储所有数据,而不是每填写一项就保存一次。我们对代码稍做修改,如下面这样,就符合标准,也更符合日常实际。

var obj = localStorage.getItem("o");
obj.x = 2;
obj.y = 3;
localStorage.setItem("o", obj);

Web存储事件

一旦页面的localStorage或者sessionStorage发生改变,那么当前的同源页面就会收到存储事件。需要注意的是数据发生改变的页面不会收到事件。可以通过addEventListener()方法注册事件处理程序,代码如下:

window.addEventListener("storage", function(event){
    /*
    event的几个重要属性:
    1.key
    项目名字
    2.newValue
    新值
    3.oldVlue
    旧值
    4.storageArea
    存储对象
    5.url
    触发存储事件的文档URL
    */
})

需要注意的是,由于存储事件采用的是广播机制,因此localStorage会广播所有访问同一站点的窗口,比如我们在首页设置停止动画,那么所有其他详情页都会收到广播事件,从而都停止动画,sessionStorage则不会这样。

Cookie

Cookie是一种比较古老的技术。它最初的目的是为了让服务器识别客户端身份,以便给不同身份的客户端提供个性化服务,这就是我们说的动态网页技术。Cookie是动态网页的基石,由于Http协议是无状态的,每次请求完成后就关闭连接,因此状态保持无法通过Http协议自身来完成,Cookie解决了这个问题。Cookie的使用非常简单,和上面的Web存储类似,这里不多做介绍。需要注意的是Cookie的有效期可以通过max-age进行设置。另外Cookie也严格遵守同源策略,作用域可以通过path和domain进行设置,Cookie只对当前页和当前页的子路径下的页面是可见的。

Cookie的局限性

Cookie的特殊之处在于每次请求都会带上Cookie信息,就好比你每次去政府机关办事都必须带上身份证一样,因此Cookie不太适合存储大量的信息。RFC2965标准不允许浏览器保存超过300个Cookie,同时为每个Web服务器保存的Cookie不能超过20个,而且每个Cookie保存的数据不能超过4K。理论上来说,Cookie的数量和大小都不应该做任何限制,但是出于性能的考虑,我们在实际应用中就不得不做上述限制。

其他客户端存储

IE userData

在IE5以上的版本中,可以给Html元素附加一个userData行为,从而使该元素具有load和save方法,用于载入和保存客户端存储的数据。它的作用域比Cookie小,只在当前目录有效,不包含子目录,存储的数据量比Cookie大。具体的,可查阅更详细的相关文档。因为该功能只在IE上有效,因此适用范围很有限。

应用程序存储

和localStorage不同的,应用程序存储不是仅仅保存数据,而是将整个页面保存下来。同时应用程序缓存不会因为清除浏览器缓存而清除掉,它更像是一个安装在浏览器端的一个固定的应用。除非是用户手动删除,否则它就永久的驻扎在那里。应用程序缓存包含一系列页面,是一个完整的网页应用。因此,它有一个缓存清单。有关应用程序缓存,需要较大篇幅叙述,具体的,可以参考更专业的文档。应用程序存储是HTML5标准新增的功能,各主流浏览器都支持。

好了,关于客户端存储就是这些,你都掌握了吗?

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

推荐阅读更多精彩内容