绝大多数的软件都需要使用某种具有持久性的方式来存储数据,Web Apps 也不例外,涉及到完整后台的 Web Apps ,可以直接在后台使用 mysql 等数据库来存储数据,但过多的 sql 查询会影响服务器性能,甚至是整个 App 的性能。因此,一些简单有效的存储方式对与 Web Apps 显得很重要,Web Storage 似乎正是为此而设计。下面开始正式介绍 Web Storage 。

一. Web Storage 是什么?

Web Storage 是 HTML5 中用于在客户端存储数据的方法,有两种形式:localStorage(本地存储)和 sessionStorage(会话存储)。这两种方法都允许使用 JavaScript 设置“键值对”,并保存在客户端中,在重新加载页面时读出它们。熟悉 Web 开发的读者会发现,这与 cookie 的机制很相似,但与 cookie 相比,它们有很大的差异:

cookie

cookie 不适合大量数据的存储,因为它们由每个对服务器的请求来传递,这使得 cookie 速度很慢而且效率也不高。

Web Storage

Web Storage 的数据完全存储在客户端,不需要通过浏览器的请求再传输到服务器,这样不但可以存储更多的数据,速度也较快。并且,Web Storage 具有统一的编程接口,使得数据操作更为简便。

二. localStorage(本地存储)和 sessionStorage(会话存储)

上面有提及,Web Storage 有 localStorage 和 sessionStorage 两种形式,它们在功能上是一样的,只是持久性和范围有所不同,具体如下:

1. localStorage

localStorage 方式存储的数据没有时间限制,即使浏览窗口关闭了,数据也会保存下来,这些数据也可用于所有来自同源(即域名,协议和端口均要相同)窗口(或者标签页)的加载,实际开发中用于 Web Apps 的选项设置或用户偏好设置会很有用。

2. sessionStorage

sessionStorage 方式存储的数据实际上存储在窗口对象中,当关闭浏览器窗口后,数据会被删除。由于这些数据是存储于窗口对象中,所以它们对于其他窗口或标签页不可见。实际开发中可以用于记录暂时的状态或排序。

三. 浏览器支持

关于浏览器对 Web Storage 的支持情况需要分开 API 和事件两个方面进行说明

1. API 支持情况

IE8+ ,Chrome 4+ , Firefox 3.5+ , Safari 4+ 和 Opera 10.5+ 对于 Web Storage API 有良好及基本统一的支持,

2. 事件支持情况

相对于 API ,Storage 的事件比较晚才有良好的浏览器支持,具体如下:Firefox 5+ , Safari 5+ , Chrome 12+ , Opera 10.5 + 和 IE9+

四. 使用 Web Storage API

下面会例举一些例子说明如何设置、访问和删除 Web Storage 。例子中会统一使用 localStorage ,但实际上在这些例子中使用 localStorage 或 sessionStorage 并没有区别,不过读者需要注意 sessionStorage 在关闭窗口或标签页后会丢失。

但在之前 Kayo 需要说明一点,对于不同的域(包括子域),Web Storage 的数据存储于不同的区域,并且一个网站只能访问其自身的数据。这也是 localStorage 只能访问同源窗口或标签页的原因。

1. 设置

localStorage.setItem('username', 'Kayo'); // 设置 username 为 Kayo

2. 访问

var username = localStorage.getItem('Kayo'); // 访问 username 并把其键值存储在一个变量 username 中

3. 删除

localStorage.removeItem('username'); // 删除 username 键

以上是标准的 Web Storage 基本操作,实际上还有另外一系列更实用的操作方式,假如开发者的键是有效的 JavaScript token (即没有空格、没有除下划线之外的标点),那么可以使用如下的操作方式:

localStorage.username = 'Kayo'; // 设置 username 为 Kayo
var username = localStorage.username; // 访问 username 并把其键值存储在一个变量 username 中
delete localStorage.username; // 删除 username 键

由于 Web Storage 的操作基于 JavaScript ,因此 Kayo 建议使用第二种操作方式,这样会更加方便并且利于整段 JavaScript 代码的阅读。

除了上面三种基本操作外,Web Storage 还包括一个 length 属性以及以下两个方法:

4. clear()

清空一个域下的全部键值。

5. key(n)

返回一个域下 localStorage 列表或 sessionStorage 列表的第 n 个键的键名。

6. length

返回一个域下 localStorage 列表或 sessionStorage 列表的键的总数。

五. 实例

在说明了 Web Storage 的基本使用后,下面举例说明 Web Storage 的具体使用。Web Storage 虽然相对 cookie 可以存储更大的数据量,但这里的更大只是数据的大小,由于 Web Storage 采用的是“键值对”的存储方式,即一个“键名”对应一个值,这样并不利于处理大量的数据,因此 Web Storage 更适合存储辅助性的数据,尤其是处理大量相同性质的数据时,Web Storage 便显得很不灵活。在例子中,Kayo 会以大家比较熟悉的保存用户留言信息进行说明,即使用 Web Storage 代替大家熟悉的 cookie 记录用户留言信息。

例子中会有一个表单,填入表单的内容并提交,但这里会阻止默认的表单提交动作,改以存储在 localStorage ,为了方便操作,会把设置、访问键值写成独立的函数,具体的情况可以测试完整 Demo (为了简化例子结构,这里只使用 addEventListener 监听事件,请使用 Chrome, Firefox 等现代浏览器浏览 Demo ,下同)。测试方法:填写相关信息,提交表单,刷新页面,观察用户信息部分是否得到保留,为了更容易理解 Web Storage 的使用,例子中并没有制作相应的后台,并且由于阻止了表单提交,提交表单不会出现反馈,因此提交表单后直接刷新页面即可。

下面列出例子中主要的代码。

主要 HTML 结构

<form action="" id="add-comment" name="add-comment" /><h1>发表评论</h1><div id="userinfo"><div class="item"><span>用户名: </span><input type="text" name="username" id="username" /></div><div class="item"><span>E-mail: </span><input type="email" name="email" id="email" /></div><div class="item"><span>网址: </span><input type="text" name="website" id="website" /></div></div><div class="item"><span>评论: </span><textarea name="comment" id="comment" cols="33" rows="8"></textarea></div><div id="submit-info"><input type="submit" value="发表"></div>
</form>

JavaScript 代码

var username = document.getElementById('username'),email = document.getElementById('email'),website = document.getElementById('website'),submit = document.getElementById('submit');// 加载已保存的 localStorage
function loadUserInfo(){username.value = localStorage.username;email.value = localStorage.email;website.value = localStorage.website;
}// 存储表单数据为 localStorage
function saveUserInfo(){localStorage.username = username.value;localStorage.email = email.value;localStorage.website = website.value;
}// 打开页面时加载数据
loadUserInfo();// 使用存储表单数据为 localStorage 代替表单提交
submit.addEventListener('click', function(e){e.preventDefault();saveUserInfo();
});

从代码量上看,由于例子比较简单,因此这并不会比 cookie 版的代码量少,但结构却简洁很多,并且操作方式很简单,即使增加更多的信息项也很方便。

除此之外,在本系列文章的第一篇中,Kayo 介绍了一个使用 jQuery Mobile 和 HTML5 开发的作品,其中“设置”的功能也是利用 Web Storage 制作,详情可以浏览第一篇文章的第六部分“作品”。

六. Web Storage 事件

Web Storage 支持一个 "storage" 事件,Web Storage 中的数据被保存后,修改或删除,都会触发 storage 事件。但由于浏览器对于该事件的支持并不完善,因此实际上在大多浏览器中,"storage" 并没有完全按照上面所说的触发。在介绍 "storage" 事件的实际效果时,Kayo 先介绍一下该事件的具体情况。

"storage" 事件会把一系列的属性封装在相应的 event 对象中,用于绑定事件回调函数内部调用,具体的属性如下:

  • key 返回发生变化的 key (即键名)
  • oldValue 返回发生变化的 key 的原值(即改变前的值)
  • newValue 返回发生变化的 key 的新值(即改变后的值)
  • url 返回触发事件的 URL
  • storageArea 返回触发事件的对象

这里需要提醒一点,Storage 的 事件需要在带有域名的目录下才能触发,即需要 Web 服务的支持,直接打开相应的文件并不能触发 Storage 事件,而 Storage 的 API 则无须这样。

接下来对上面的例子进行扩展,监听其中的 Web Storage ,你可以点击下面的 Demo 进行测试。这里问题就会出现了,在 Chrome 22 , Firefox 16 , Safari 5.1 中,直接改变表单中的值并提交是不会触发 "storage" 事件,但当用户打开两个 Demo 标签,改变其中一个标签中表单的值并提交,另一个页面反而会触发事件。事实上在较低版本的这三款浏览器中也会出现这个情况,这似乎是这三款浏览器对于 Web Storage 的处理机制并不完善。也因为这样,Kayo 并不建议在实际开发中利用 "storage" 事件。

监听 storage 事件

function triggerEvent(e){var tips = 'key:' + e.key + ', newValue:' + e.newValue + ', oldValue:' + e.oldValue + ', url:' + e.url + ', storageArea:' + e.storageArea;alert(tips);
}window.addEventListener('storage', triggerEvent, true);

完整 Demo 。

七. 不足之处

Web Storage 虽然功能强大并且使用也很方便,但实际上它仍存在一些问题,除了上面有提及的浏览器支持仍存在不足外,安全问题也是开发者必须注意的重要问题。W3C 为开发者列出了以下三点安全问题:

1. DNS 欺骗攻击 (DNS spoofing attacks)

因为一些潜在的 DNS 欺骗攻击,Web Storage 无法保证发出请求的脚本所在域是当前的域,这意味着域 A 中嵌入域 B 的脚本,该脚本可以访问域 A 的 Web Storage 。为了尽量减轻这种情况发生,可以使用对页面 TLS 。使用 TLS 可以确保用户或软件代表真实使用者,这样其他页面需要使用能确定它们来自同一域的 TLS 证书才可以访问 storage 。

2. 跨目录攻击 (Cross-directory attacks)

若不同的用户共享使用一个域名,例如几位用户共用 abc.com 域名,所有人都将会共享 abc.com 下的 storage 对象,但没有任何特性可以限制特定访问路径。因此不建议共享域名的用户使用 Web Storage ,这样可以避免域名下的其他用户可以阅读你的 Web Storage 甚至重写它们。

即使可以限制访问的路径,也可以利用 DOM 脚本安全模型轻松地跳过这保护并访问数据。当然,Web Storage 是存储在本地端,如果这些共享域名的用户之间不会接触到其他人的本地端,那这个问题就不用担心了。

3. 实施风险 (Implementation risks)

当使用这些持久化存储特性时,会让有不好意图的网站跨域阅读到这些数据,甚至还会让这些网站写入信息,然后再跨域利用这些信息。

直白的说,让第三方网站写入持久性的数据可能会导致信息泄漏,例如:一个域上的一个用户购买清单可以被另一个域作为定向广告。

最后关于兼容性的问题,由于移动端上的主流浏览器(Android, IOS 的系统浏览器, opera 等现代浏览器)对于 Web Storage 乃至很多 HTML5 的特性支持已经很完善和统一,如果你是利用这项特性开发 Web Apps ,兼容性的问题反而不用过于担心,这也是使用 HTML5 开发 Web Apps 的重要优势。

因此,虽然 Web Storage 仍会存在一些不足,但从综合的角度考虑,Web Storage 已经具有很好的实用价值。利用 Web Storage 保存一些非机密的设置信息无疑是 Web Apps 开发中一个很好的选择。

原文由 Kayo Lee 发表,原文链接:http://kayosite.com/web-app-by-jquery-mobile-and-html5-web-storage.html

使用 jQuery Mobile 与 HTML5 开发 Web App (十六) —— HTML5 Web Storage相关推荐

  1. 使用 jQuery Mobile 与 HTML5 开发 Web App (十九) —— HTML5 对 Web App 的影响

    在本系列文章的开头,Kayo 曾经介绍过 Web App 的优缺点,并且说明了 HTML5 在其中起的作用,当然,Web Apps 的发展需要 HTML5 , CSS 与 JavaScript 以及后 ...

  2. 使用 jQuery Mobile 与 HTML5 开发 Web App (十八) —— HTML5 Web Workers

    本文要介绍的是 HTML5 的 Web Workers 特性,它解决了 JavaScript 开发中一个重大的问题 -- 在后台运行 JavaScript .与本系列前两篇文章介绍的特性相似,Web ...

  3. 转载:用Dreamweave cs 5.5+PhoneGap+Jquery Mobile搭建移动开发

    转载地址:http://blog.csdn.net/haha_mingg/article/details/7900221 移动设备应用开发有多难,只要学会HTML5+Javascript就可以.用Dr ...

  4. 分享一个超棒的在线jQuery mobile原型设计开发工具 - codiqa

    在线演示  本地下载 今天我们分享一个超棒的在线jQuery mobile原型设计开发工具:Codiqa,这个在线设计工具能够帮助我们快速的使用拖拽的方式来构建一个jQuery mobile的web应 ...

  5. 开发app要用html吗,为什么要使用HTML5开发手机APP?

    为什么要使用HTML5开发手机APP?从未来的发展趋势看,现在的大部分开发商都因为HTML5的便捷性而广泛使用它,而且使用HTML5可以带来更好的互动.从程序员开发的角度来讲,HTML5的代码更加清晰 ...

  6. Android逆向工程:针对HTML5开发的App如何下手?这就带你上车!

    亲爱的小伙伴们大家好,春节已经过去了,想必小伙伴们在家玩的都很愉快吧~现在不知道大家是否已经告别了老家温暖的港湾再次投入到工作岗位中,博主反正是已经投入到岗位一星期了,不过还是有点不在状态~~新年新气 ...

  7. UWP开发入门(十六)——常见的内存泄漏的原因

    原文:UWP开发入门(十六)--常见的内存泄漏的原因 本篇借鉴了同事翔哥的劳动成果,在巨人的肩膀上把稿子又念了一遍. 内存泄漏的概念我这里就不说了,之前<UWP开发入门(十三)--用Diagno ...

  8. SAP UI5 应用开发教程之六十六 - 基于 OData V4 的 SAP UI5 表格控件如何实现删除功能试读版

    一套适合 SAP UI5 初学者循序渐进的学习教程 教程目录 SAP UI5 本地开发环境的搭建 SAP UI5 应用开发教程之一:Hello World SAP UI5 应用开发教程之二:SAP U ...

  9. SAP UI5 应用开发教程之五十六 - SAP UI5 树控件(tree)的开发试读版

    一套适合 SAP UI5 初学者循序渐进的学习教程 教程目录 SAP UI5 本地开发环境的搭建 SAP UI5 应用开发教程之一:Hello World SAP UI5 应用开发教程之二:SAP U ...

最新文章

  1. Android端WEEX + HTTPDNS 最佳实践
  2. IE6与其他浏览器的区别
  3. 二进制搭建kubernetes多master集群【三、配置k8s master及高可用】
  4. SQL语法练习 - 使用WITH AS提高性能简化嵌套SQL
  5. 深入理解React(一)JSX与虚拟DOM
  6. 1155: 零起点学算法62——输出矩阵
  7. 【转载】Android设计中的.9.png
  8. 在tornado里面使用reverse_url
  9. 通过代码生成机制实现强类型编程-CodeSimth版
  10. NPM包管理器跟换国内镜像CNPM
  11. spring实现事务原理
  12. 当ThreadLocal碰上线程池
  13. Git ignore UserInterfaceState.xcuserstate
  14. iPhone4 降级6.12教程 无须SHSH 不装插件 不睡死[转载] by 轻鸢
  15. 绘制电气电路中的电阻——Visio制图总结【电控类】(二)
  16. 分享nbsp;康奈尔大学做笔记的方法
  17. CDISC STANDARD
  18. 协议栈之packet_type
  19. 今生梦一场,思念你的殇
  20. 第九届全国大学生GIS应用技能大赛下午(试题及参考答案含数据)

热门文章

  1. 训练日志 2018.12.9
  2. 联络员(信息学奥赛一本通-T1393)
  3. 信息学奥赛一本通C++语言——1097: 画矩形
  4. 4.4.3 日期与时间计算
  5. 什么工作经常出差_商旅人群洞察:什么样的人经常坐飞机出差?
  6. C语言 memset函数简单实现
  7. python idle打不开_孩子,给你的Python安个家吧!
  8. python:文件打包为exe
  9. python使用全局变量的坑,要使用global
  10. torch.backends.cudnn.benchmark--提升卷积神经网络的运行速度