WebStorageW3C标准第二版

来源:互联网 发布:淘宝商城儿童电动车 编辑:程序博客网 时间:2024/06/05 00:43

翻译自W3C WebStorage推荐标准第二版,水平有限,若有翻译错误或不恰当的地方欢迎指正。

1 简介

此规范引入了两个相关联的机制,机制的目的和Http session cookies一样,就是为了在客户端储存name-value形式的键值对。
第一个机制的使用场景是用户不仅可以在一个窗口中进行一次单独的交易,也可以同时可以在多个窗口中进行多个交易。
Cookie并不能很好的处理这种场景,举例来说,一个用户可能在同一个网站的两个不同窗口中买飞机票,如果使用cookie去跟踪用户机票的购买情况,当用户点击从一个页面进入另一个页面时,用户正在购买的机票将会从一个窗口“泄露”到另一个当中,这很可能导致用户在不知情的情况下购买了同一航班的两张机票。

以下是一个sessionStorage使用的例子,在页面中有一个checkbox,用户点击去表示自己需要保险:

<label>  <input type="checkbox" onchange="sessionStorage.insurance = checked ? 'true' : ''">  I want insurance on this trip.</label>

之后的页面中就可以通过脚本去检查是否已经点击了这个checkbox:

if (sessionStorage.insurance) { ... }

如果用户在一个网站中打开了多个窗口,那么每个窗口中将有其独立的session storage对象副本。

第二个机制的使用场景是为了使storage可以横跨多个窗口中去使用,而且其存在的时间不仅仅局限于当前会话。尤其是Web应用出于客户端性能的原因也希望可以存储兆字节为单位的用户数据,比如用户的整个创作文档或是用户的邮箱内容。
localStorage接口被用于实现对页面local storage域的访问。

以下是一个localStorage使用的例子,网站example.com可以通过在页面最后添加如下脚本来实现对用户登录网站次数的统计:

<p>  You have viewed this page  <span id="count">an untold number of</span>  time(s).</p><script>  if (!localStorage.pageLoadCount)    localStorage.pageLoadCount = 0;  localStorage.pageLoadCount = parseInt(localStorage.pageLoadCount) + 1;  document.getElementById('count').textContent = localStorage.pageLoadCount;</script>

每一个网站都有其独立的storage域。

2 一致性要求

所有的图表、实例以及记录部分以及显明标注非规范的内容不属于规范的一部分,除此之外的其他内容都是规范中的内容。
规范中所提出的算法或步骤,只要结果相同可以以任何方式去实现。
唯一的一个在规范中被定义了一致性的用户代理(User-agent)。
用户代理在输入上强行规定了一些实现规范,目的是防止不受限制的输入。比如,可以防止拒绝服务攻击,防止内存耗尽或是解决特定平台限制的问题。
当对一个功能的支持被禁用时(比如为了缓解安全问题的紧急措施,帮助开发,或是为了性能原因),User agents必须体现对这个功能的不支持,而且要体现此功能没有在此规范中提及。比如,一个特殊的功能是通过 一个Web IDL接口中的属性去访问,而这个属性本身将会从实现了这个接口的对象中被省略,将属性留在这个对象上但使其返回空或者抛出一个异常都是不足的。

2.1 依赖

此规范依赖了其他几个底层的规范。
HTML
许多HTML的基础规范在此规范中使用
WEBIDL
此规范的IDL部分符合WEBIDL规范中定义的IDL片段

3 术语

“一个Foo对象”中的Foo其实是一个接口,和“一个实现了Foo接口的对象”这种精确说法意思的一样的。
DOM一般是指Web应用的脚本中可以使用的一系列API,而不是指Document对象或是其他在DOM规范中定义的Node对象。
一个IDL属性在它的值被取回(比如被开发者的脚本)时为getting状态,当新的值被分配给它的时候它的状态为setting
我们使用JavaScript而不是官方名词的ESMAScript被用来指ECMA2User agent

IN THIS ARTICLE
Learn more
General knowledge
Technical reference
A user agent is a computer program representing a person, for example, a browser in a Web context.62,因为JavaScript使用的更加广泛。

另补充几个术语,来自MDN:

Browsing context: A browsing context is the environment in which a browser displays a Document (normally a tab nowadays, but possibly also a window or a frame within a page).

Origin: Web content’s origin is defined by the scheme (protocol), host (domain), and port of the URL used to access it. Two objects have the same origin only when the scheme, host, and port all match.

User agent: A user agent is a computer program representing a person, for example, a browser in a Web context.

4 API

4.1 Storage 接口

interface Storage {  readonly attribute unsigned long length;  DOMString? key(unsigned long index);  getter DOMString? getItem(DOMString key);  setter void setItem(DOMString key, DOMString value);  deleter void removeItem(DOMString key);  void clear();};

每一个Storage对象都提供了对一系列key/value键值对的访问,这些key/value有时被称为item,key为字符串,任何字符串(包括空字符串)都是有效的key,value和key同理。

每一个Storage对象在创建时都与一系列键值对相关联,与sessionStoragelocalStorage属性中定义的相似。多个不相关的实现了Storage接口的对象可以同时与一系列相同的键值对相关联。

Length属性必须返回当前存在的与对象相关联的键值对的数量。

key(n)方法必须返回列表中第n个key 的名字,由用户代理去定义key的顺序,但是只要key的数量不变,就必须保持在对象内的一致性。(因此增加或者删除一个key或许会改变key的顺序但唯独不能允许去改变一个已有的key的值),如果n的值大于等于键值对的数量那么这个方法必须返回null。Storage对象上支持的属性名是当下存在的与该对象相关联的每一个键值对的key的值。

getItem(key)用于返回当前key对应的value的值,如果key不存在则必须返回null。

setItem(key, value) 方法必须先检查key是否存在,如果不存在则将对应的键值对添加到list中。如果该key已经存在,则使用value值对此键值对进行更新。如果value值与已有的value值相同则此方法不执行任何操作

如果不能设置新值的话,这个方法必须抛出QuotaExceededError异常(设置新的value值失败的原因有比如Storage被用户禁用或者list的配额已经超过了限度)。

removeItem(key)方法,如果key存在,则从list中将对应key的键值对进行删除,如果key不存在则不执行任何操作

setItem()和removeItem()方法对于操作失败的情况必须是具有原子性的,在失败的情况下这两个方法必须不执行任何操作。即对Storage的操作只会有两种结果,一种是操作成功另一种是Storage完全不发生任何变化。

clear() 方法必须是原子性的,这一操作是在list不为空的情况下将list清空,如果list没有任何内容则不执行任何操作。

注意:
当以上 setItem(), removeItem(), 和clear()方法被调用时,其他Document的Window对象的事件被触发使得可以访问更新后的数据,如sessionStorage和localStorage属性部分所定义。

注意:
以上方法不要求去等待数据写入磁盘,只要求不同脚本访问同样的键值对时数据要保证一致性。

4.2 sessionStorage属性

[NoInterfaceObject]interface WindowSessionStorage {  readonly attribute Storage sessionStorage;};Window implements WindowSessionStorage;

sessionStorage属性专用于表示当前顶层浏览上下文存储区集合。

每个顶级浏览上下文都有一组唯一的会话存储区域,每个源都有一个。

用户代理不应该在浏览器上下文会话储存区域中将数据置为过期,但是当用户请求将数据删除、UA发现存储区域存在限制或是出于安全原因则可以将数据置为过期。用户代理应当避免在可以访问数据的脚本正在运行时去删除数据。

当顶级浏览器上下文环境被销毁时(也意味着用户永远都不能再去访问),用户存储在sessionStorage中的数据也可以随其被消除,因为本规范中描述的 api 没有提供任何方法来检索这些顶级浏览器上下文环境被销毁后其所保存的数据。

注意:
浏览器上下文环境的生命周期可以与具体的用户代理进程本身无关,因为用户代理可能支持在重启后恢复会话。

当一个新的Document在一个拥有顶级浏览环境的浏览器上下文中被创建时,用户代理必须检查顶级浏览器上下文环境是否为文档的源提供了一个sessionStorage域,如果提供了则这个域就分配给这个Document,如果没有的话,必须创建一个Storage域给这个文档的源,然后再为Document分配sessionStorage域。为Document分配的Storage域在Document的生命周期内都不会改变。

注意:
当一个iframe被移动到另一个Document中时,其中内嵌的原有浏览器上下文被销毁并创建一个新的。

sessionStorage属性必须返回一个与Document分配的Storage域相关联的Storage对象(如果这个域存在的话),否则则返回null。每个Document都必须为其Window的sessionStorage分配一个独立的对象。

当一个顶级浏览器上下文环境通过克隆一个已经存在的浏览器上下文去创建时,新的浏览器上下文中的sessionStorage必须与之前的相同,不过这两个上下文环境应当被视作隔离的而且不能以任何方式相互影响。

当script脚本在一个已经存在的浏览器上下文中创建一个新的顶级浏览器上下文环境、用户通过点击已存在的浏览器上下文中的链接或是通过其他方式与一个具体的Document相关联时,如果这次浏览器上下文的创建并不会创建一个新的sessionStorage,那么源Document中的sessionStorage必须在新上下文环境被创建的时候复制到其中。

当在与sessionStorage域相关联的Storage对象x上调用setItem(), removeItem(), 和clear()这几个方法时,如果方法执行没有出现异常或是像上文所提到的未执行任何操作,那么对于每一个其Window对象的sessionStorage属性的Storage对象与同一个存储域相关联的Document对象来说,除了对象x之外,都要需要发送一个storage消息通知。

4.1 localStorage属性

[NoInterfaceObject]interface WindowLocalStorage {  readonly attribute Storage localStorage;};Window implements WindowLocalStorage;

localStorage对象为源(Origin)提供了Storage对象。用户代理必须有一系列的localStorage域集合,每一个对应一个源。

用户代理只有在安全原因或是用户的请求下才能去将localStorage数据域中的数据置为过期。用户代理应当始终避免去删除正在被脚本访问运行中的数据。

当localStorage属性被访问时,用户代理必须运行以下几个步骤,这些步骤被称为Storage对象初始化步骤

  1. 如果请求违反了一些政策决定(比如用户代理被配置为不允许页面保存数据),那么用户代理会抛出SecurityError并不执行这些步骤也不会返回一个Storage对象。
  2. 如果Document的源不是 scheme/host/port格式的元组,那么就抛出一个SecurityError异常并舍弃这些步骤。
  3. 要去检查用户代理是否已经为源的Document的Window对象这一可以访问localStorage的对象分配了localStorage数据域,如果没有则为这个源创建一个新的数据域。
  4. 返回与这个源的localStorage数据域相关联的Storage对象。每一个Document必须提供一个独立的对象给它对应的Window对象的localStorage属性。

当在与localStorage域相关联的Storage对象x上调用setItem(), removeItem(), 和clear()这几个方法时,如果方法执行没有出现异常或是像上文所提到的未执行任何操作,那么对于每一个其Window对象的localStorage属性的Storage对象与同一个存储域相关联的Document对象来说,除了对象x之外,都要需要发送一个storage消息通知。
当localStorage属性的Storage对象被检索、返回、设置或删除的任何时候(不论其是否直接属性访问的一部分),在属性枚举过程中检查属性的存在性时,在确定存在的属性数量时,或是作为任何一个定义在Storage接口上的方法或属性执行过程的一部分时,用户代理都必须先获得存储互斥量(storage mutex)。

4.4 storage事件

如前两个章节所讲,当storage数据域发生变化时,storage事件在Document的window对象中触发。当用户代理将要发送一个Document的storage通知时,用户代理必须做一个任务队列以便于去触发一个受信任的storage事件,这个事件不能被终止或取消,它使用了StorageEvent接口,并且作为Document对象的Window对象的一个属性。

0 0