使用Web存储API

TODO:本文由 赤石俊哉 翻译整理,您可以将本文自由地用于学习交流。如需用于其他用途请征得作者的同意。
原文链接:Using the Web Storage API - Mozilla Developer Network (英文)


Web存储API提供了浏览器可以在本地安全存储键值对的一个机能,它比cookies更为直观。这篇文章将会简单阐述一下如何来简单地使用这种技术。

基础概念

存储对象是一个简单的键值存储,它跟对象类似,但是它们在页面读取后依然完整。键和值总是字符串(注意,整型数据也会自动地转为字符串,就像对象那样)。你可以像访问一个对象一样来访问这些值,或者使用方法:Storage.getItem()Storage.setItem()。下面这三行都是设置了colorSetting记录:

localStorage.colorSetting = '#a4509b';
localStorage['colorSetting'] = '#a4509b';
localStorage.setItem('colorSetting', '#a4509b');

Note: 强烈推荐使用Web存储API(setItem, getItem, removeItem, key, length)进行纯对象的键值操作来防止可能出现的隐患。

两种Web存储中包含的机能如下:

  • sessionStorage 为每一个页面访问session期间维持一个单独的存储空间(只要浏览器打开就一直维持,包括页面重载和重新存储)。

  • localStorage 做同样的事情,只不过在浏览器被关闭再打开后仍然维持着。

这些机能可以通过Window.sessionStorageWindow.localStorage属性(更准确的说,在支持的浏览器中,Window对象实现了WindowLocalStorageWindowSessionStorage对象,他们是由localStoragesessionStorage挂起的)——调用其中任何一个,都会创建一个Storage对象的实例,透过它,数据项目可以被设置,取回,和移除。每一个sessionStoragelocalStorage的源都是用不同的存储对象——它们是分辨运作和被控制的。

所以,第一次在文档中调用localStorage后,它会返回一个Storage对象,调用sessionStorage之后,他又会返回另一个Storage对象。它们都可以用同一种方式进行操控,但是都是彼此独立的。

localStorage 功能检测

为了能使用localStorage,我们应该先进行确认,当前的浏览器会话是否支持和允许使用它。

测试支持和可用性

如果浏览器支持localStorage,在它的window对象中就会有一个属性叫作localStorage。但是,由于种种原因,如果直接去断定这个属性是否存在可能会抛出异常。如果它确实存在,也没有保障我们就一定可以使用它,因为很多浏览器支持在设定中禁用localStorage。举个例子,那就是Safari,在隐私浏览模式下,他会给我们一个配额为0的空的localStorage对象,实际上就是使它无效化。我们在检测的时候,也应该把这一点考虑进来。

下面是一个用于检测localStorage是否支持以及可用的方法:

function storageAvailable(type) {
try {
var storage = window[type],
x = '__storage_test__';
storage.setItem(x, x);
storage.removeItem(x);
return true;
}
catch(e) {
return false;
}
}

你应该这样使用它:

if (storageAvailable('localStorage')) {
// Yippee! We can use localStorage awesomeness
}
else {
// Too bad, no localStorage for us
}

你可以用相同的办法来测试sessionStoragestorageAvailable('sessionStorage')

你可以参考一下localStorage功能检测简报(英文)

一个简单的例子

为了举例说明一些典型的Web存储用例,我们创建了一个简单的例子,叫它Web Storage Demo吧。登录页面提供了一个控件来自定义颜色,字体,和装饰图片:

当你选择不同的选项,页面会实时地更新,顺带一提,你的选项会被存储到localStorage里存储。所以当你离开页面重新载入它的时候,你的选择会被记住。

我们也提供了一个事件输出页面——如果你在另一个标签页中载入这个页面,那么你在登录页面中做出的任何选择之后,你会看到更新了的存储信息会被显示出来,因为StorageEvent被触发了。

Note: 你可以从这里查看源代码

检测你的数据是否被填充成功

拿上面的例子来说,在main.js中,我们将会测试存储对象是否已经被填入(也就是说页面是否之前就已经载入过了):

if(!localStorage.getItem('bgcolor')) {
populateStorage();
} else {
setStyles();
}

Storage.getItem()方法被用于从存储中获取数据项目。在这个例子中,我们测试bgcolor项目是否存在。如果不存在,我们运行populateStorage()来将已经存在的自定义值存入存储。如果已经有数据了,我们运行setStyle()以使用存储的值来更新页面的样式。

Note: 你也可以使用Storage.length来测试存储对象是否为空。

从存储中获取数据

就像之前我们所描述的,数据可以从存储中使用Storage.getItem()来获取。这个方法使用键来做参数,它会返回相应的数据的值。举个例子:

function setStyles() {
var currentColor = localStorage.getItem('bgcolor');
var currentFont = localStorage.getItem('font');
var currentImage = localStorage.getItem('image'); document.getElementById('bgcolor').value = currentColor;
document.getElementById('font').value = currentFont;
document.getElementById('image').value = currentImage; htmlElem.style.backgroundColor = '#' + currentColor;
pElem.style.fontFamily = currentFont;
imgElem.setAttribute('src', currentImage);
}

在这里,前三行从本地存储中取出数据,接下来我们使用这些值设置显示的表单元素。所以当我们重新读取页面的时候,它们会保持同步。最后,我们更新了页面上的样式和装饰图片,所以你的自定义数值都在重载页面之后重现了。

在存储中设置值

Storage.setItem()可以用于创建也可以用于更新数据的值。它需要两个参数——需要修改或者创建的键名,需要存储的值。

function populateStorage() {
localStorage.setItem('bgcolor', document.getElementById('bgcolor').value);
localStorage.setItem('font', document.getElementById('font').value);
localStorage.setItem('image', document.getElementById('image').value); setStyles();
}

populateStorage()方法在本地存储中设置了三个项目——背景颜色,字体,图片路径。然后运行setStyles()方法更新页面样式,等等。

我们也在每一个表单元素上包含了一个onchange句柄,当表单的值发生改变时,数据和样式会立刻进行更新。

bgcolorForm.onchange = populateStorage;
fontForm.onchange = populateStorage;
imageForm.onchange = populateStorage;

使用StorageEvent在存储做出改变时进行响应

StorageEvent会在Storage对象发生变化时进行相应。它不能很好地在发生改变的页面上进行相应,但是在同一个域名的页面之间同步任何变化时,这是会是一个不错的方法。在不同的域名中无法访问相同的存储对象。

在事件页面(events.js)中,只有如下的代码:

window.addEventListener('storage', function(e) {
document.querySelector('.my-key').textContent = e.key;
document.querySelector('.my-old').textContent = e.oldValue;
document.querySelector('.my-new').textContent = e.newValue;
document.querySelector('.my-url').textContent = e.url;
document.querySelector('.my-storage').textContent = e.storageArea;
});

这里我们添加了一个事件监听器给window对象,当当前源的存储对象发生改变时引发。就如你所能看见的,这个事件的参数包含了很多有用的信息——发生变化的键名,旧值,新值,发生变化的文档的URL,以及存储对象其自身。

删除数据记录

Web存储也提供了一对简单的方法来移除数据。在我们的demo中没有使用这些,把它们加到我们的项目里面来也不难。

  • Storage.removeItem()使用一个简单的参数(你想要移除的数据项目的键)来将它从域名下的存储对象中移除它。

  • Storage.clear()是一个无参方法,它会清空域名下所有的存储对象。

浏览器兼容性

桌面

特 性 Chrome Firefox(Gecko) Internet Explorer Opera Safari(Webkit)
localStorage 4 3.5 8 10.50 4
sessionStorage 5 2 8 10.50 4

移动

特 性 Android Firefox Mobile(Gecko) IE Phone Opera Mobile Safari Mobile
基础支持 2.1 ? 8 11 iOS 3.2

Storage 事件

当一个存储区域(本地存储和会话存储)被修改时,storage事件会被触发。

通用信息

规范 Web Storage
接口 StorageEvent
冒泡
可取消
目标 DefaultView(<window>)
默认动作

属性

属性 类型 描述
target readonly EventTarget 事件的目标(DOM树中最顶层的目标)
type readonly DOMString 事件的类型
bubbles readonly Boolean 事件是否冒泡(bubbles)
cancelable readonly Boolean 事件是否可以取消
key readonly DOMString(string) 被修改的键名
oldValue readonly DOMString(string) 旧的值
newValue readonly DOMString(string) 新的值
url readonly DOMString(string) 更新该键名的文档的地址
storageArea readonly Storage 被影响的存储对象

使用Web存储API存取本地数据的更多相关文章

  1. 渐进式web应用开发---ajax本地数据存储(四)

    在前几篇文章中,我们使用service worker一步步优化了我们的页面,现在我们学习使用我们之前的indexedDB, 来缓存我们的ajax请求,第一次访问页面的时候,我们请求ajax,当我们继续 ...

  2. IOS中NSUserDefaults的用法(轻量级本地数据存储)

    NSUserDefaults适合存储轻量级的本地数据,比如要保存一个登陆界面的数据,用户名.密码之类的,个人觉得使用NSUserDefaults是首选.下次再登陆的时候就可以直接从NSUserDefa ...

  3. 理解 Android 本地数据存储 API

    利用首选项.SQLite 和内部及外部内存 API 对于需要跨应用程序执行期间或生命期而维护重要信息的应用程序来说,能够在移动设备上本地存储数据是一种非常关键的功能.作为一名开发人员,您经常需要存储诸 ...

  4. HTML5权威指南--Web Storage,本地数据库,本地缓存API,Web Sockets API,Geolocation API(简要学习笔记二)

    1.Web Storage HTML5除了Canvas元素之外,还有一个非常重要的功能那就是客户端本地保存数据的Web Storage功能. 以前都是用cookies保存用户名等简单信息.   但是c ...

  5. 临时存存储页面上的数据---Web存储

    HTML5 Web存储的两种方法使用 localStorage和sessionStorage 参考: http://www.cnblogs.com/taoweiji/archive/2012/12/0 ...

  6. Android本地数据存储复习

    Android本地数据存储复习 Android无论是应用层还是系统层都需要在本地保存一些数据,尤其在应用层中使用的就更为普遍,大体有这么几种:SharedPreference,file,sqlite数 ...

  7. Windows 8 应用开发 - 本地数据存储

    原文:Windows 8 应用开发 - 本地数据存储      在应用中通常会遇到用户主动或被动存储信息的情况,当应用关闭后这些数据仍然会存储在本地设备上,用户下次重新激活应用时会自动加载这些数据.下 ...

  8. iOS开发技术分享(1)— iOS本地数据存储

    iOS开发技术分享(1)— iOS本地数据存储 前言: 我本是一名asp.net程序员,后来加入了iOS游戏开发队伍,到现在也有一年多的时间了.这一年来,每天都干到2.3点钟才睡觉,不为别的,只为了学 ...

  9. html5 之本地数据存储

    HTML5 提供了两种在客户端存储数据的新方法: localStorage - 没有时间限制的数据存储 sessionStorage - 针对一个 session 的数据存储 cookie与webSt ...

随机推荐

  1. Vue 源码解读(11)—— render helper

    前言 上一篇文章 Vue 源码解读(10)-- 编译器 之 生成渲染函数 最后讲到组件更新时,需要先执行编译器生成的渲染函数得到组件的 vnode. 渲染函数之所以能生成 vnode 是通过其中的 _ ...

  2. 当我们看到phpinfo时在谈论什么

    我们在渗透测试的过程中,如果存在phpinfo界面,我们会想到什么? 大部分内容摘抄自:https://www.k0rz3n.com/2019/02/12/PHPINFO 中的重要信息/ 关于phpi ...

  3. ARP协议、路由器详细工作原理

    ARP原理分析 第一次通信时,有对方IP地址但是没有目标MAC地址,该PC就会在网络层启动ARP协议生成一个ARP报文"我叫1.1,我的MAC是AA;谁是1.3,你的MAC是多少?" ...

  4. laravel resource风格

    resource 风格 概念 一种软件架构风格.设计风格,而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存 ...

  5. docker学习笔记(3)- 镜像

    简介 在docker学习笔记(1)- 架构概述一节中可以看到镜像是docker三大组件之一,可以将Docker镜像类比为虚拟机的模版. 镜像由多个层组成,每层叠加之后从外部看就像一个独立的对象,镜像的 ...

  6. LGP5591题解

    题意很明确,不说了. 前置芝士:单位根反演 也就是: \[[n|a]=\frac 1 n \sum_{i=0}^{n-1}w_n^{ai} \] 看到题目给的柿子: \[\sum_{i=0}^n\bi ...

  7. ASP.NET Core 6.0对热重载的支持

    .NET 热重载技术支持将代码更改(包括对样式表的更改)实时应用到正在运行的程序中,不需要重启应用,也不会丢失应用状态. 一.整体介绍 目前 ASP.NET Core 6.0 项目都支持热重载.在以下 ...

  8. .net为程序集签名之.pfx文件

    项目中误删了.pfx证书文件,导致项目无法启动. 以为很快就能在网上找到解决方案,应该没关系,不过找了半个小时,都没有有效的解决办法,搜出来很多.pfx文件是一个证书文件,里面存储公钥和私钥,对于我要 ...

  9. 解决Ubuntu虚拟机占用空间与实际空间不符问题

    1.背景 右键点击Windows中的Ubuntu虚拟机文件夹,发现它占用Windows磁盘空间大小140GB: 然后进入Ubuntu,输入 df -hl 可以算出实际占用空间也大约为140GB.在Ub ...

  10. OpenCV开发笔记(七十四):OpenCV3.4.1+ffmpeg3.4.8交叉编译移植到海思平台Hi35xx平台

    前言   移植opencv到海思平台,opencv支持对视频进行解码,需要对应的ffmpeg支持.   Ffmpeg的移植   Ffmpeg的移植请参考之前的文章:<FFmpeg开发笔记(十): ...