Web存储允许我们在浏览器里保存简单的键/值数据。Web存储和cookie很相似,但它有着更好的实现方式,能保存的数据量也很大。这两种类型共享相同的机制,但是被保存数据的可见性和寿命存在区别。

PS:还有一种存储规范名为“索引数据库API”(Indexed Database API),它允许保存富格式数据和进行SQL风格的查询。

1.使用本地存储

我们可以通过全局属性 localStorage访问本地存储功能。这个属性会返回一个Storage 对象,下表对其进行了介绍。Storage 对象被用来保存键/值形式的字符串对。

Storage 对象可用来存储键/值对,其中键和值都是字符串。键必须是惟一的,这就意味着如果我们用 Storage对象里已经存在的键调用setItem方法,就会更新它的值。下面的示例展示了如何添加、修改和清除本地存储中数据。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用本地存储</title>
<style>
body > * {float: left;}
table {border-collapse: collapse;margin-left:50px; }
th,td {padding: 4px;}
th {text-align: right;}
input {border: thin solid black;padding: 2px;}
label {min-width: 50px;display: inline-block;text-align: right;}
#countmsg,#buttons {margin-left: 50px;margin-top: 5px;margin-bottom: 5px;}
</style>
</head>
<body>
<div>
<div><label>Key:</label><input id="key" placeholder="Enter Key" /></div>
<div><label>Value:</label><input id="value" placeholder="Enter Value" /></div>
<div id="buttons">
<button id="add">Add</button>
<button id="clear">Clear</button>
</div>
<p id="countmsg">These are <span id="count"></span> items </p>
</div>
<table id="data" border="1">
<tr><th>Item Count:</th><td id="count">-</td> </tr>
</table>
<script>
displayData();
var buttons = document.getElementsByTagName("button");
for(var i=0;i<buttons.length;i++){
buttons[i].onclick = handleButtonPress;
}
function handleButtonPress(e){
switch (e.target.id){
case 'add':
var key = document.getElementById("key").value;
var value = document.getElementById("value").value;
localStorage.setItem(key,value);
displayData();
break;
case 'clear':
localStorage.clear();
displayData();
break;
}
}
function displayData(){
var tableElem = document.getElementById("data");
tableElem.innerHTML = "";
var itemCount = localStorage.length;
document.getElementById("count").innerHTML = itemCount;
for(var i=0;i<itemCount;i++){
var key = localStorage.key(i);
var val = localStorage[key];
tableElem.innerHTML += "<tr><th>" + key + ":</th><td>" + val + "</td></tr>";
}
}
</script>
</body>
</html>

此例报告了本地存储中的项目数量,并枚举已保存的键/值对来填充一个表格元素。这里添加了两个button元素,在Add按钮被按下时将他们的内容保存为项目。在响应Clear按钮时,会清除本地存储中的内容。其显示效果如下:

浏览器不会删除我们用 localStorage对象添加的数据,除非用户自己清除浏览数据。

监听存储事件

通过本地存储功能保存的数据对所有来源相同的文档都是可用的。某个文档对本地存储进行修改时会触发storage事件,我们可以监听其他同源文档上的这个事件来确保我们能跟上最新的变化。

与storage事件同时指派的对象是一个StorageEvent对象,它的成员如下表所示:

下面的示例展示了一个文档,它会监听并编录本地存储对象上触发的事件。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>编录本地存储事件</title>
<style>
table {border-collapse:collapse; }
th,td {padding: 4px;}
</style>
</head>
<body>
<table id="data" border="1">
<tr>
<th>key</th>
<th>oldValue</th>
<th>newValue</th>
<th>url</th>
<th>storageArea</th>
</tr>
</table>
<script>
var tableElem = document.getElementById("data");
window.onstorage = handleStorage;
function handleStorage(e){
var row = "<tr>";
row += "<td>" + e.key + "</td>";
row += "<td>" + e.oldValue + "</td>";
row += "<td>" + e.newValue + "</td>";
row += "<td>" + e.url + "</td>";
row += "<td>" + (e.storageArea == localStorage) + "</td>";
row += "</tr>";
tableElem.innerHTML += row;
}
</script>
</body>
</html>

storage事件是通过Window对象触发的,此对象可以来自共享被改动存储的任何一个文档。此例中,每次接收到事件时都会给table元素添加一个新行,演示效果如下:

图中的事件展示了给本地存储添加新项目的过程。url属性能帮助我们了解是哪个文档触发了变化。storageArea属性会返回发生变化的Storage对象,它可以是本地或会话存储对象。此例只接收来自本地存储对象的事件。

PS:这些事件不会再制造变化的文档内指派。

2. 使用会话存储

会话存储(session storage)的工作方式和本地存储很接近,不同之处在于数据是各个浏览上下文私有的,会在文档被关闭时移除。我们通过全局变量 sessionStorage访问会话存储,它会返回一个Storage对象。下面的例子展示了会话存储的用法:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用会话存储</title>
<style>
body > * {float: left;}
table {border-collapse: collapse;margin-left:50px; }
th,td {padding: 4px;}
th {text-align: right;}
input {border: thin solid black;padding: 2px;}
label {min-width: 50px;display: inline-block;text-align: right;}
#countmsg,#buttons {margin-left: 50px;margin-top: 5px;margin-bottom: 5px;}
</style>
</head>
<body>
<div>
<div><label>Key:</label><input id="key" placeholder="Enter Key" /></div>
<div><label>Value:</label><input id="value" placeholder="Enter Value" /></div>
<div id="buttons">
<button id="add">Add</button>
<button id="clear">Clear</button>
</div>
<p id="countmsg">These are <span id="count"></span> items </p>
</div>
<table id="data" border="1">
<tr><th>Item Count:</th><td id="count">-</td> </tr>
</table>
<script>
displayData();
var buttons = document.getElementsByTagName("button");
for(var i=0;i<buttons.length;i++){
buttons[i].onclick = handleButtonPress;
}
function handleButtonPress(e){
switch (e.target.id){
case 'add':
var key = document.getElementById("key").value;
var value = document.getElementById("value").value;
sessionStorage.setItem(key,value);
displayData();
break;
case 'clear':
sessionStorage.clear();
displayData();
break;
}
}
function displayData(){
var tableElem = document.getElementById("data");
tableElem.innerHTML = "";
var itemCount = sessionStorage.length;
document.getElementById("count").innerHTML = itemCount;
for(var i=0;i<itemCount;i++){
var key = sessionStorage.key(i);
var val = sessionStorage[key];
tableElem.innerHTML += "<tr><th>" + key + ":</th><td>" + val + "</td></tr>";
}
}
</script>
</body>
</html>

此例的工作方式和前面本地存储的例子很接近,不同之处在于可见性和寿命受到限制。这些限制会影响storage事件的处理方式:前面提到的storage事件只会在共享存储的文档中触发。对于会话存储,这就意味着事件只会在内嵌文档中触发,比如 iframe里的文档。修改前一示例如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>使用会话存储的storage事件</title>
<style>
body > * {float: left;}
table {border-collapse: collapse;margin-left:50px; }
th,td {padding: 4px;}
th {text-align: right;}
input {border: thin solid black;padding: 2px;}
label {min-width: 50px;display: inline-block;text-align: right;}
#countmsg,#buttons {margin-left: 50px;margin-top: 5px;margin-bottom: 5px;}
iframe {clear: left;}
</style>
</head>
<body>
<div>
<div><label>Key:</label><input id="key" placeholder="Enter Key" /></div>
<div><label>Value:</label><input id="value" placeholder="Enter Value" /></div>
<div id="buttons">
<button id="add">Add</button>
<button id="clear">Clear</button>
</div>
<p id="countmsg">These are <span id="count"></span> items </p>
</div>
<table id="data" border="1">
<tr><th>Item Count:</th><td id="count">-</td> </tr>
</table>
<br />
<iframe src="storage-02.html" width="666" height="222"></iframe></div>
<script>
displayData();
var buttons = document.getElementsByTagName("button");
for(var i=0;i<buttons.length;i++){
buttons[i].onclick = handleButtonPress;
}
function handleButtonPress(e){
switch (e.target.id){
case 'add':
var key = document.getElementById("key").value;
var value = document.getElementById("value").value;
sessionStorage.setItem(key,value)
displayData();
break;
case 'clear':
sessionStorage.clear();
displayData();
break;
}
}
function displayData(){
var tableElem = document.getElementById("data");
tableElem.innerHTML = "";
var itemCount = sessionStorage.length;
document.getElementById("count").innerHTML = itemCount;
for(var i=0;i<itemCount;i++){
var key = sessionStorage.key(i);
var val = sessionStorage[key];
tableElem.innerHTML += "<tr><th>" + key + ":</th><td>" + val + "</td></tr>";
}
}
</script>
</body>
</html>

其演示效果如下:

来源:《HTML5权威指南》(《The Definitive Guide to HTML5》)

【高级功能】使用Web存储的更多相关文章

  1. Oracle_高级功能(4) 数据库存储结构

    数据库存储结构分为:物理存储结构和逻辑存储结构.物理结构和逻辑结构分开,对物理数据的存储不会影响对逻辑结构的访问.1.物理存储结构 数据库文件 os block2.逻辑存储结构 tablespace ...

  2. Tengine是由淘宝网发起的Web服务器项目。它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性

    简介 Tengine是由淘宝网发起的Web服务器项目.它在Nginx的基础上,针对大访问量网站的需求,添加了很多高级功能和特性.Tengine的性能和稳定性已经在大型的网站如淘宝网,天猫商城等得到了很 ...

  3. MVC5 Entity Framework学习之Entity Framework高级功能(转)

    在之前的文章中,你已经学习了如何实现每个层次结构一个表继承.本节中你将学习使用Entity Framework Code First来开发ASP.NET web应用程序时可以利用的高级功能. 在本节中 ...

  4. MVC5 Entity Framework学习之Entity Framework高级功能

    在之前的文章中,你已经学习了怎样实现每一个层次结构一个表继承. 本节中你将学习使用Entity Framework Code First来开发ASP.NET web应用程序时能够利用的高级功能. 在本 ...

  5. 为ASP.NET MVC应用程序使用高级功能

    为ASP.NET MVC应用程序使用高级功能 这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译, ...

  6. Xen之初体验:XenMotion、 StorageMotion、Site Recovery、Power Management 各种新、高级功能免费

    Xenserver 的新版本6.2现在已经全面开源,省掉了原有的序列号,也能免费体验曾经标题中的付费高级功能. 安装镜像:http://downloadns.citrix.com.edgesuite. ...

  7. 【读书笔记】HTML5 Web存储

    PS:这里讲web存储,主要是在客户端存储的一些技术:cookie,localstorage,sessionstorage,WebSQL.     Cookie   Cookie是HTML4中在客户端 ...

  8. 【温故而知新-Javascript】使用Web存储

    Web存储允许我们在浏览器里保存简单的键/值数据.Web存储和cookie很相似,但它有着更好的实现方式,能保存的数据量也很大.这两种类型共享相同的机制,但是被保存数据的可见性和寿命存在区别. PS: ...

  9. HTML学习之Web存储(五)

    本地数据库功能大大增强了Web应用对于本地存储数据的方式和功能.Web时代真正进入了:“客户端为重,服务端为轻的时代”. <!DOCTYPE html> <html xmlns=&q ...

随机推荐

  1. Shell最多可以输入多少个参数?

    在脚本编写过程中,通常会涉及到参数的输入.譬如,sh 1.sh 10 20,在执行1.sh这个脚本中,10即为第一个参数,20即为第二个参数.有时,就会有这个疑惑,即shell脚本最多可以支持多少个变 ...

  2. Unity3D默认的快捷键

    shift +方向键             向“向方向键前进” Windows系统Unity3D中的快捷键 组合键 键 功能 File 文件 Ctrl   N New Scene 新建场景 Ctrl ...

  3. PHP将部分内容替换成星号

    在最近的项目中,会碰到到某人的手机号码隐藏中间几位,身份证号码只显示末尾4位的需求.当时一开始是网上搜索了一下,看到有人是用substr_replace这个函数来替换的,后面我也用了这个函数,但在用的 ...

  4. elasticsearch 查询(match和term)

    elasticsearch 查询(match和term) es中的查询请求有两种方式,一种是简易版的查询,另外一种是使用JSON完整的请求体,叫做结构化查询(DSL). 由于DSL查询更为直观也更为简 ...

  5. Android开发中遇到的requestFeature() must be called before adding content异常

    缘起 上一篇博文中讲到了几种实现全屏显示Activity内容的方法.然而实际在实现中发现了一些问题,在本篇博文中进行总结下.首先交代一下开发环境,本人使用的是Android Studio 1.5.1, ...

  6. Socket开发框架之数据加密及完整性检查

    在前面两篇介绍了Socket框架的设计思路以及数据传输方面的内容,整个框架的设计指导原则就是易于使用及安全性较好,可以用来从客户端到服务端的数据安全传输,那么实现这个目标就需要设计好消息的传输和数据加 ...

  7. 走进异步世界:EnyimMemcached异步化改造引起的内存泄漏

    6月30日我们发布了异步化改造后的博客程序之后,出现了高内存.高CPU.高线程数的不理想情况. 经过一周的追查,终于水落日出——引起不理想情况的根源是我们修改过的EnyimMemcached代码存在内 ...

  8. EntityFramework中几种更改数据的方式

    首先声明个实体类,该实体类是EntityFrameWork自动生成的,对应数据表Test结构如下 public partial class Test { public int Id{ get; set ...

  9. PYTHON3连接MYSQL数据库

    http://smilejay.com/2013/03/python3-mysql-connector/ Python 2.x 上连接MySQL的库倒是不少的,其中比较著名就是MySQLdb(Djan ...

  10. Scalaz(23)- 泛函数据结构: Zipper-游标定位

    外面沙尘滚滚一直向北去了,意识到年关到了,码农们都回乡过年去了,而我却留在这里玩弄“拉链”.不要想歪了,我说的不是裤裆拉链而是scalaz Zipper,一种泛函数据结构游标(cursor).在函数式 ...