浏览器客户端存储
如何使用客户端存储 API 来存储应用数据
由 JavaScript APIs 组成,允许你在客户端存储数据(比如在用户的机器上),而且可以在需要的时候重新取得需要的数据。好处:
- 个性化网站偏好(比如显示一个用户选择的窗口小部件,颜色主题,或者字体)。
- 保存之前的站点行为 (比如从先前的session中获取购物车中的内容, 记住用户是否之前已经登陆过)。
- 本地化保存数据和静态资源可以使一个站点更快(至少让资源变少)的下载, 甚至可以在网络失去链接的时候变得暂时可用。
- 保存web已经生产的文档可以在离线状态下访问。
经常客户端和服务端存储是结合在一起使用的。例如,你可以从数据库中下载一个由网络游戏或音乐播放器应用程序使用的音乐文件,将它们存储在客户端数据库中,并按需要播放它们。用户只需下载音乐文件一次——在随后的访问中,它们将从数据库中检索。
客户端存储 API 可以存储的数据量是有限的(可能是每个API单独的和累积的总量);具体的数量限制取决于浏览器,也可能基于用户设置。参考浏览器存储限制和清理标准
1、传统方法:cookies
早期的网络时代开始,网站就使用 cookies 来存储信息,以在网站上提供个性化的用户体验。它们是网络上最早最常用的客户端存储形式。
因为在那个年代,有许多问题——无论是从技术上的还是用户体验的角度——都是困扰着 cookies 的问题。这些问题非常重要,以至于当第一次访问一个网站时,欧洲居民会收到消息,告诉他们是否会使用 cookies 来存储关于他们的数据,而这是由一项被称为欧盟 Cookie 条例的欧盟法律导致的。
由于这些原因,我们不会在本文中教你如何使用 cookie。毕竟它过时、存在各种安全问题,而且无法存储复杂数据,而且有更好的、更现代的方法可以在用户的计算机上存储种类更广泛的数据。
cookie 的唯一优势是它们得到了非常旧的浏览器的支持,所以如果您的项目需要支持已经过时的浏览器(比如 Internet Explorer 8 或更早的浏览器),cookie可能仍然有用,但是对于大多数项目来说,您不需要再使用它们了。
为什么仍然有新创建的站点使用 cookies?这主要是因为开发人员的习惯,使用了仍然使用cookies的旧库,以及存在许多web站点,提供了过时的参考和培训材料来学习如何存储数据。
2、新流派:Web Storage 和 IndexedDB
现代浏览器有比使用 cookies 更简单、更有效的存储客户端数据的 API。
- Web Storage API 提供了一种非常简单的语法,用于存储和检索较小的、由名称和相应值组成的数据项。当您只需要存储一些简单的数据时,比如用户的名字,用户是否登录,屏幕背景使用了什么颜色等等,这是非常有用的。
- IndexedDB_API 为浏览器提供了一个完整的数据库系统来存储复杂的数据。这可以用于存储从完整的用户记录到甚至是复杂的数据类型,如音频或视频文件。
3、未来:Cache API
一些现代浏览器支持新的 Cache API
这个API是为存储特定HTTP请求的响应文件而设计的,它对于像存储离线网站文件这样的事情非常有用,这样网站就可以在没有网络连接的情况下使用。
缓存通常与 Service Worker API 组合使用,尽管不一定非要这么做。
简单的例子:离线文件存储
4、存储简单数据 — web storage
Web Storage API 非常容易使用 — 你只需存储简单的 键名/键值 对数据 (限制为字符串、数字等类型) 并在需要的时候检索其值。
基本语法
a、访问 GitHub 上的 web storage blank template b、打开你浏览器开发者工具的 JavaScript 控制台、 c、所有的 web storage 数据都包含在浏览器内两个类似于对象的结构中: sessionStorage 和 localStorage。
一种方法,只要浏览器开着,数据就会一直保存 (关闭浏览器时数据会丢失) ,而第二种会一直保存数据,甚至到浏览器关闭又开启后也是这样。我们将在本文中使用第二种方法,因为它通常更有用。 d、Storage.setItem() 方法允许您在存储中保存一个数据项——它接受两个参数:数据项的名字及其值。试着把它输入到你的JavaScript控制台
localStorage.setItem('name','Chris');
e、Storage.getItem() 方法接受一个参数——你想要检索的数据项的名称——并返回数据项的值。
var myName = localStorage.getItem('name');
myName
在输入第二行时,您应该会看到 myName 变量现在包含 name 数据项的值。
f、Storage.removeItem() 方法接受一个参数——你想要删除的数据项的名称——并从 web storage 中删除该数据项。
localStorage.removeItem('name');
var myName = localStorage.getItem('name');
myName
第三行现在应该返回 null — name 项已经不存在于 web storage 中。
数据会一直存在
web storage 的一个关键特性是,数据在不同页面加载时都存在(甚至是当浏览器关闭后,对 localStorage 的而言)
在不同的浏览器中再次打开Web Storage 空白模板
localStorage.setItem('name','Chris');
var myName = localStorage.getItem('name');
myName
你应该看到 name 数据项返回,现在关掉浏览器再把它打开
var myName = localStorage.getItem('name');
myName
你应该看到,尽管浏览器已经关闭,然后再次打开,但仍然可以使用该值。
为每个域名分离储存
每个域都有一个单独的数据存储区(每个单独的网址都在浏览器中加载). 你 会看到,如果你加载两个网站(例如google.com和amazon.com)并尝试将某个项目存储在一个网站上,该数据项将无法从另一个网站获取。
这是有道理的 - 你可以想象如果网站能够查看彼此的数据,就会出现安全问题!
更复杂的例子
示例将允许你输入一个名称,然后该页面将刷新,以提供个性化问候。这种状态也会页面/浏览器重新加载期间保持,因为这个名称存储在Web Storage 中。
示例文件:personal-greeting.html 这包含一个具有标题,内容和页脚,以及用于输入您的姓名的表单的简单网站。
a、首先创建对所有需要在此示例中操作的HTML功能的引用 - 我们将它们全部创建为常量,因为这些引用在应用程序的生命周期中不需要更改。
// 创建所需的常量
const rememberDiv = document.querySelector('.remember');
const forgetDiv = document.querySelector('.forget');
const form = document.querySelector('form');
const nameInput = document.querySelector('#entername');
const submitBtn = document.querySelector('#submitname');
const forgetBtn = document.querySelector('#forgetname');
const h1 = document.querySelector('h1');
const personalGreeting = document.querySelector('.personal-greeting');
接下来,我们需要包含一个小小的事件监听器,以在按下提交按钮时阻止实际的提交表单动作自身,因为这不是我们想要的行为。
// 当按钮按下时阻止表单提交
form.addEventListener('submit', function(e) {
e.preventDefault();
});
现在我们需要添加一个事件监听器,当单击 Say hello 按钮时,它的处理函数将会运行。这些注释详细解释了每一处都做了什么,但实际上我们在这里获取用户输入到文本输入框中的名字并使用setItem()
将它保存在网络存储中,然后运行一个名为 nameDisplayCheck()
的函数来处理实际的网站文本的更新。
// run function when the 'Say hello' button is clicked
submitBtn.addEventListener('click', function() {
// store the entered name in web storage
localStorage.setItem('name', nameInput.value);
// run nameDisplayCheck() to sort out displaying the
// personalized greetings and updating the form display
nameDisplayCheck();
});
此时,我们还需要一个事件处理程序。以便在单击 Forget 按钮时运行一个函数——且仅在单击 Say hello 按钮(两种表单状态来回切换)后才显示。在这个功能中,我们使用removeItem()
从网络存储中删除项目name,然后再次运行 nameDisplayCheck()
以更新显示。
// run function when the 'Forget' button is clicked
forgetBtn.addEventListener('click', function() {
// Remove the stored name from web storage
localStorage.removeItem('name');
// run nameDisplayCheck() to sort out displaying the
// generic greeting again and updating the form display
nameDisplayCheck();
});
nameDisplayCheck()
函数:在这里,我们通过使用 localStorage.getItem('name')
作为测试条件来检查 name 数据项是否已经存储在 Web Storage 中。如果它已被存储,则该调用的返回值为 true,如果没有,它会是false。如果是true,我们会显示个性化问候语,显示表格的 forget 部分,并隐藏表格的 Say hello 部分。如果是 false,我们会显示一个通用问候语,并做相反的事。
// define the nameDisplayCheck() function
function nameDisplayCheck() {
// check whether the 'name' data item is stored in web Storage
if(localStorage.getItem('name')) {
// If it is, display personalized greeting
let name = localStorage.getItem('name');
h1.textContent = 'Welcome, ' + name;
personalGreeting.textContent = 'Welcome to our website, ' + name + '! We hope you have fun while you are here.';
// hide the 'remember' part of the form and show the 'forget' part
forgetDiv.style.display = 'block';
rememberDiv.style.display = 'none';
} else {
// if not, display generic greeting
h1.textContent = 'Welcome to our website ';
personalGreeting.textContent = 'Welcome to our website. We hope you have fun while you are here.';
// hide the 'forget' part of the form and show the 'remember' part
forgetDiv.style.display = 'none';
rememberDiv.style.display = 'block';
}
}
最后:我们需要在每次加载页面时运行 nameDisplayCheck() 函数。如果我们不这样做,那么个性化问候不会在页面重新加载后保持。
document.body.onload = nameDisplayCheck;
注意:在完成版本的源代码中, <script src="index.js" **defer**></script>
一行里, defer 属性指明在页面加载完成之前,<script>元素的内容不会执行。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论