什么是 Web 存储?
Web 存储通常与 HTTP Cookie 相仿。与 Cookie 类似,Web开发人员可以将每次会话或域特定的数据作为名称/值对存储在使用 Web 存储的客户端上。但是,与 Cookie不同的是,在控制某个窗口存储的信息如何向其他窗口显示时,Web 存储要更为简单。
例如,用户可能会打开两个浏览器窗口,购买两个不同航班的机票。然而,如果航空公司的 Web 应用程序使用 Cookie存储其会话状态,那么相关信息可能会从一笔交易“泄露”至另一笔交易,进而导致用户可能在未得到通知的情况下购买了同一航班的两张机票。因为应用程序的脱机行为(例如将值存储在本地以便稍后返回服务器)功能变得越来越强大,所以此类信息“泄露”的风险也会越来越大。
另外,Web 存储提供的磁盘空间也比 Cookie 要大得多。在 Windows Internet Explorer中,Cookie 只能存储 4 千字节 (KB) 的数据。此字节既可以是一个 4 KB 的名称/值对,也可以是总大小为 4 KB 的20 个名称/值对。相比之下,Web 存储为每个存储区域提供了约 10 兆字节 (MB) 的大小。
从功能上来说,客户端存储区域则与 Cookie 完全不同。Web 存储并不像 Cookie那样使用每个请求将值传送给服务器,而且本地存储区域中的数据也不会过期。与 Cookie 的另一不同点是,Web存储可使用标准接口访问单个数据,而这个标准接口也越来越受浏览器供应商的支持。
Web 存储脚本对象
- window.sessionStorage
- window.localStorage
- 存储对象
window.sessionStorage
会话存储适用于用户执行单笔交易的情况。 window
对象的 sessionStorage 属性为所有在单个选项卡生存期内(顶级浏览上下文期间)加载的页面维护密钥/值对。例如,某个页面可能包含一个复选框。如果用户选中此复选框,则表示该用户想要保险。
(label) (input type="checkbox"
onchange="sessionStorage.insurance = checked") I want insurance on
this
trip. (/label)
之后的页面可能通过脚本来检查该用户是否选中了此复选框。
if(sessionStorage.insurance) { ... }
Storage
对象支持扩展属性(例如前一个示例中的“保险”)。如果该属性名称不存在,那么将创建一个密钥/值对来保存此名称。请注意,密钥/值对将始终作为字符串进行存储。必须将不同的数据类型(如数字、布尔值和结构化数据)转换为字符串,才能持久保存在存储区域。
当值保存到 sessionStorage
后,运行在同一上下文中的不同页面上的脚本便可以对其进行检索。加载另一文档后,同一原 URL的sessionStorage便会从内存中初始化。(请参阅安全和隐私部分以获取详细信息。)
注意
尽管 HTML5 允许,但Internet Explorer 8还是不会在浏览器崩溃恢复后继续 sessionStorage。
window.localStorage
本地存储机制扩展至多个窗口,并在当前会话之外仍保持运行。 localStorage
属性为域提供一致的存储区域。该属性允许 Web 应用程序将近 10 MB的用户数据(如全部文档或用户的收件箱)存储在客户端上来改善性能。
例如,某个网站可以使用以下脚本显示用户已访问某个页面的次数。
(p) You have viewed thispage (span id=
"count"
)an untold number of(/span) time(s).
(/p) (script)
var storage = window.localStorage;
if
(!storage.pageLoadCount) storage.pageLoadCount = 0; storage.pageLoadCount = parseInt(storage.pageLoadCount,
10
) + 1; document.getElementByIdx_xx_x(
'count'
).innerHTML = storage.pageLoadCount;
注意
pageLoadCount递增之前,必须用 parseInt 方法 (JScript 5.6) 转换为数字。
每个域和子域都有其单独的本地存储区域。域可访问子域的存储区域,子域也可以访问父域的存储区域。例如,example.com
及其所有子域都可以访问 localStorage['example.com']
。子域 localStorage['www.example.com']
可供example.com
访问,但不可由其他子域访问,如mail.example.com
。
存储对象
会话和本地存储对象均支持以下属性和方法。
主题 内容
clear 将所有的密钥/值对从 Web 存储区域删除。
constructor 返回指向某个对象的构造函数的引用。
getItem 检索与 Web 存储密钥关联的当前值。
key 检索集合中指定索引处的值。
length 检索密钥/值列表的长度。
remainingSpace 检索存储对象所允许的剩余 UTF-16 字符数。
removeItem 将某个密钥/值对从Web 存储集合中删除。
setItem 设置密钥/值对。
Web 存储事件
每次更新存储区域中的数据时,Internet Explorer都会激发事件,这样便能在多个浏览器实例或多个选项卡之间同步相关信息。
支持以下事件。
- onstorage
- onstoragecommit
onstorage
onstorage
将在存储区域发生变化时于 document 中激发。所有共享同一会话上下文的文档,以及当前显示正在提交本地存储的同一个域或子域的页面的所有文档都会接收到此事件。
如果目标 document
对象当前为不活动状态,那么 Internet Explorer 将不会激发任何事件。
onstoragecommit
Internet Explorer 使用 XML文件来保存本地存储。 onstoragecommit
事件将在本地存储写入磁盘时激发。
安全和隐私
本地存储中保存的数据的公开度要远大于 Cookie中保存的数据,后者可能只限于某个域中的一个特定路径。即便使用一个难以猜出的密钥也无法确保隐私不被侵犯,因为 Storage
对象可提供一种枚举密钥的方法。
你可以考虑以下操作:
- 顶级浏览上下文和主机名
- 来源决定存储限制
- 清除存储区域
顶级浏览上下文和主机名
顶级浏览上下文限制了对会话存储区域的访问。在 Internet Explorer中,会为每个选项卡创建一个新的浏览上下文。一个顶级浏览上下文中运行的脚本没有权限访问另一个顶级浏览上下文中创建的存储。站点可以将数据添加至会话存储中,并且该主机名中同一窗口打开的任何页面都可以访问该数据。
要点
此次检查不包括评估端口和协议/方案。
来源决定存储限制
磁盘配额限制是设置该限制值的页面所在域决定的,而不是设置该值的域所决定。这可以防止恶意脚本用尽相关域的存储配额。也可以避免这些脚本使用随机子域来存储无限量的数据。
计算出的存储大小将作为所有密钥名称和值的总长度,一个存储区域可以容纳多达 1000万字节。remainingSpace
属性用于确定可用存储空间。
清除存储区域
关闭最后一个引用会话状态数据的窗口后,该会话状态便会立即释放。但是,任何时候,用户都可以清除存储区域,方法是单击Internet Explorer 的“工具”
菜单中的“删除浏览历史记录”,然后选中Cookie 复选框,最后单击“确定”。此操作将清除所有不在“收藏夹”文件夹中的域的会话和本地存储区域,并重置注册表中的存储配额。清除“保留收藏夹站点数据”复选框可删除所有存储区域,无论其源是什么。
若要从存储列表中删除密钥/值对,请立即使用 removeItem
迭代集合或使用 clear 删除所有项目。请记住,所有对本地存储区域的更改都会异步保存到磁盘中。