首页 >科技周边 >IT业界 >10个客户端存储选项以及何时使用它们

10个客户端存储选项以及何时使用它们

Christopher Nolan
Christopher Nolan原创
2025-02-10 14:22:12901浏览

10 Client-side Storage Options and When to Use Them

浏览器数据存储与操作,也称为客户端存储,在无需或无法将数据发送到Web服务器时非常有用。

浏览器数据存储和操作的场景包括:

  • 保持客户端应用程序的状态——例如当前屏幕、输入的数据、用户偏好等。
  • 访问本地数据或文件且具有严格隐私要求的实用程序。
  • 可离线工作的渐进式Web应用程序 (PWA)。

以下是十种浏览器数据存储选项:

  1. JavaScript变量
  2. DOM节点存储
  3. Web存储 (localStorage 和 sessionStorage)
  4. IndexedDB
  5. 缓存API(不要使用AppCache!)
  6. 文件系统访问API
  7. 文件和目录条目API
  8. cookie
  9. window.name
  10. WebSQL

本文将探讨这十种不同的浏览器数据存储方式,涵盖它们的限制、优缺点以及每种技术的最佳用途。

在浏览这些选项之前,先快速了解一下数据持久性……

关键要点

  • JavaScript变量:临时数据最快,但在页面刷新时会被清除;最适合不需要持久保存超过当前页面查看的数据。
  • DOM节点存储:在速度和持久性方面与JavaScript变量类似,但允许在HTML元素中存储状态;用于组件特定状态。
  • Web存储 (localStorage 和 sessionStorage):适合持久存储少量数据 (localStorage) 或按会话存储数据 (sessionStorage);由于同步操作,不适合大型数据集。
  • IndexedDB:最适合需要持久保存的大量结构化数据;支持事务和索引,但API复杂。
  • 缓存API:理想情况下,用于在PWA中存储网络响应以供离线使用;现代API,但仅限于网络数据,不适合通用状态存储。
  • cookie:对于必须与HTTP请求一起发送的小型数据很有用;具有良好的持久性,但容量有限且可能存在安全问题。

数据持久性

通常,您存储的数据将是:

  1. 持久性:它会一直保留,直到您的代码选择删除它,或者
  2. 易失性:它会一直保留,直到浏览器会话结束,通常是在用户关闭选项卡时。

实际情况更为细致。

持久性数据可能随时被用户、操作系统、浏览器或插件阻止或删除。当浏览器接近分配给该存储类型的容量时,它可能会决定删除较旧或较大的项目。

浏览器还会记录页面状态。您可以从网站导航离开,然后单击后退或关闭并重新打开选项卡;页面应该看起来相同。被视为仅限会话的变量和数据仍然可用。

  1. JavaScript变量

指标 说明 容量没有严格限制,但当您填充内存时,浏览器可能会变慢或崩溃读取/写入速度最快的选项持久性差:数据会被浏览器刷新清除在JavaScript变量中存储状态是最快速和最简单的选项。我相信您不需要示例,但是……

<code class="language-javascript">const
  a = 1,
  b = 'two',
  state = {
    msg:  'Hello',
    name: 'Craig'
  };</code>

优点:

  • 易于使用
  • 快速
  • 不需要序列化或反序列化

缺点:

  • 易碎:刷新或关闭选项卡会清除所有内容
  • 第三方脚本可以检查或覆盖全局(窗口)值

您已经在使用变量了。您可以在页面卸载时考虑永久存储变量状态。

  1. DOM节点存储

指标 说明 容量没有严格限制,但不适合大量数据读取/写入速度快持久性差:数据可能被其他脚本或刷新清除大多数DOM元素(在页面上或内存中)都可以在命名属性中存储值。使用以data-为前缀的属性名称更安全:

  1. 属性将永远不会具有关联的HTML功能
  2. 您可以通过dataset属性访问值,而不是更长的.setAttribute()和.getAttribute()方法。

值存储为字符串,因此可能需要序列化和反序列化。例如:

<code class="language-javascript">// 定位<main>元素
</main>const main = document.querySelector('main');

// 存储值
main.dataset.value1 = 1;
main.dataset.state = JSON.stringify({ a:1, b:2 });

// 检索值
console.log( main.dataset.value1 ); // "1"
console.log( JSON.parse(main.dataset.state).a ); // 1</code>

优点:

  • 您可以在JavaScript或HTML中定义值——例如
  • 有助于存储特定组件的状态
  • DOM很快!(与流行的观点相反)

缺点:

  • 易碎:刷新或关闭选项卡会清除所有内容(除非值是服务器渲染到HTML中的)
  • 仅限字符串:需要序列化和反序列化
  • 更大的DOM会影响性能
  • 第三方脚本可以检查或覆盖值

DOM节点存储比变量慢。在将组件的状态存储在HTML中很实用的情况下,请谨慎使用它。

  1. Web存储 (localStorage 和 sessionStorage)

指标 说明 容量每个域5MB读取/写入速度同步操作:可能很慢持久性数据保留到被清除为止Web存储提供两个类似的API来定义名称/值对。使用:

  1. window.localStorage存储持久性数据,以及
  2. window.sessionStorage在浏览器选项卡保持打开状态时保留仅限会话的数据(但请参见数据持久性)

使用.setItem()存储或更新命名项:

<code class="language-javascript">localStorage.setItem('value1', 123);
localStorage.setItem('value2', 'abc');
localStorage.setItem('state', JSON.stringify({ a:1, b:2, c:3 }));</code>

使用.getItem()检索它们:

<code class="language-javascript">const state = JSON.parse( localStorage.getItem('state') );</code>

使用.removeItem()删除它们:

<code class="language-javascript">localStorage.removeItem('state')</code>

其他属性和方法包括:

  • .length:存储的项目数
  • .key(N):第N个键的名称
  • .clear():删除所有存储的项目

更改任何值都会在连接到同一域的其他浏览器选项卡/窗口中引发存储事件。您的应用程序可以相应地做出响应:

<code class="language-javascript">const
  a = 1,
  b = 'two',
  state = {
    msg:  'Hello',
    name: 'Craig'
  };</code>

优点:

  • 简单的名称/值对API
  • 会话和持久性存储选项
  • 良好的浏览器支持

缺点:

  • 仅限字符串:需要序列化和反序列化
  • 没有事务、索引或搜索的非结构化数据
  • 同步访问会影响大型数据集的性能

Web存储非常适合更简单、更小、临时的值。它不太适合存储大量结构化信息,但是您可以通过在页面卸载时写入数据来避免性能问题。

  1. IndexedDB

指标 说明 容量取决于设备。至少1GB,但最多可以达到剩余磁盘空间的60%读取/写入速度快持久性数据保留到被清除为止IndexedDB提供了一个类似NoSQL的低级API,用于存储大量数据。该存储可以被索引,可以使用事务更新,并可以使用异步方法搜索。

IndexedDB API 复杂,需要一些事件处理。以下函数在传递名称、版本号和可选升级函数(在版本号更改时调用)时打开数据库连接:

<code class="language-javascript">// 定位<main>元素
</main>const main = document.querySelector('main');

// 存储值
main.dataset.value1 = 1;
main.dataset.state = JSON.stringify({ a:1, b:2 });

// 检索值
console.log( main.dataset.value1 ); // "1"
console.log( JSON.parse(main.dataset.state).a ); // 1</code>

以下代码连接到myDB数据库并初始化todo对象存储(类似于SQL表或MongoDB集合)。然后它定义一个名为id的自动递增键:

<code class="language-javascript">localStorage.setItem('value1', 123);
localStorage.setItem('value2', 'abc');
localStorage.setItem('state', JSON.stringify({ a:1, b:2, c:3 }));</code>

一旦db连接准备就绪,您就可以在一个事务中.add新的数据项:

<code class="language-javascript">const state = JSON.parse( localStorage.getItem('state') );</code>

您可以检索值,例如第一个项目:

<code class="language-javascript">localStorage.removeItem('state')</code>

优点:

  • 具有最大空间的灵活数据存储
  • 强大的事务、索引和搜索选项
  • 良好的浏览器支持

缺点:

  • 一个复杂的基于回调和事件的API

IndexedDB是可靠存储大量数据的最佳选择,但是您需要使用一个包装库,例如idb、Dexie.js或JsStore。

  1. 缓存API

指标 说明 容量取决于设备,但Safari将每个域限制为50MB读取/写入速度快持久性数据保留到被清除或在Safari中两周后为止缓存API提供HTTP请求和响应对象对的存储。您可以创建任意数量的命名缓存来存储任意数量的网络数据项。

该API通常用于服务工作程序中,用于缓存渐进式Web应用程序的网络响应。当设备断开网络连接时,可以重新提供缓存的资产,以便Web应用程序可以离线运行。

以下代码将网络响应存储在名为myCache的缓存中:

<code class="language-javascript">const
  a = 1,
  b = 'two',
  state = {
    msg:  'Hello',
    name: 'Craig'
  };</code>

类似的函数可以从缓存中检索项目。在此示例中,它返回响应正文文本:

<code class="language-javascript">// 定位<main>元素
</main>const main = document.querySelector('main');

// 存储值
main.dataset.value1 = 1;
main.dataset.state = JSON.stringify({ a:1, b:2 });

// 检索值
console.log( main.dataset.value1 ); // "1"
console.log( JSON.parse(main.dataset.state).a ); // 1</code>

优点:

  • 存储任何网络响应
  • 可以提高Web应用程序的性能
  • 允许Web应用程序离线运行
  • 现代基于Promise的API

缺点:

  • 不适合存储应用程序状态
  • 可能在渐进式Web应用程序之外不太有用
  • Apple对PWA和缓存API并不友好

缓存API是存储从网络检索的文件和数据的最佳选择。您可能可以使用它来存储应用程序状态,但它并非为此目的而设计,并且还有更好的选择。

5.5 AppCache

AppCache是缓存API已失效的前身。这不是您要寻找的存储解决方案。这里没有什么好看的。请离开。

  1. 文件系统访问API

指标 说明 容量取决于剩余磁盘空间读取/写入速度取决于文件系统持久性数据保留到被清除为止文件系统访问API允许浏览器读取、写入、修改和删除本地文件系统中的文件。浏览器在沙盒环境中运行,因此用户必须向特定文件或目录授予权限。这将返回一个FileSystemHandle,以便Web应用程序可以像桌面应用程序一样读取或写入数据。

以下函数将Blob保存到本地文件:

<code class="language-javascript">localStorage.setItem('value1', 123);
localStorage.setItem('value2', 'abc');
localStorage.setItem('state', JSON.stringify({ a:1, b:2, c:3 }));</code>

优点:

  • Web应用程序可以安全地读取和写入本地文件系统
  • 减少了上传文件或在服务器上处理数据的需求
  • 渐进式Web应用程序的一项很棒的功能

缺点:

  • 浏览器支持最少(仅限Chrome)
  • API可能会更改

这个存储选项最让我兴奋,但是您需要再等几年才能将其用于生产环境。

  1. 文件和目录条目API

指标 说明 容量取决于剩余磁盘空间读取/写入速度未知持久性数据保留到被清除为止文件和目录条目API提供一个可用于域的沙盒文件系统,该系统可以创建、写入、读取和删除目录和文件。

优点:

  • 可能有一些有趣的用途

缺点:

  • 非标准的、实现之间的不兼容性,以及行为可能会改变。

MDN明确指出:不要在生产网站上使用此功能。广泛的支持至少还需要几年时间。

  1. cookie

指标 说明 容量每个域80Kb(20个cookie,每个cookie最多4Kb)读取/写入速度快持久性好:数据保留到被清除或过期为止cookie是特定于域的数据。它们以跟踪人的声誉而闻名,但对于任何需要维护服务器状态的系统(例如登录)来说,它们都是必不可少的。与其他存储机制不同,cookie通常在每个HTTP请求和响应中在浏览器和服务器之间传递。两台设备都可以检查、修改和删除cookie数据。

document.cookie在客户端JavaScript中设置cookie值。您必须定义一个字符串,其中名称和值用等号(=)分隔。例如:

<code class="language-javascript">const
  a = 1,
  b = 'two',
  state = {
    msg:  'Hello',
    name: 'Craig'
  };</code>

值不能包含逗号、分号或空格,因此可能需要encodeURIComponent():

<code class="language-javascript">// 定位<main>元素
</main>const main = document.querySelector('main');

// 存储值
main.dataset.value1 = 1;
main.dataset.state = JSON.stringify({ a:1, b:2 });

// 检索值
console.log( main.dataset.value1 ); // "1"
console.log( JSON.parse(main.dataset.state).a ); // 1</code>

可以使用分号分隔符附加其他cookie设置,包括:

  • ;domain=: 如果未设置,则cookie仅在当前URL域中可用。使用;path=mysite.com允许在mysite.com的任何子域上使用它。
  • ;path=: 如果未设置,则cookie仅在当前路径及其子路径中可用。将;path=/设置为允许域中的任何路径。
  • ;max-age=: cookie到期时间(秒)——例如;max-age=60。
  • ;expires=: cookie到期日期——例如;expires=Thu, 04 July 2021 10:34:38 UTC(使用date.toUTCString()进行适当的格式化)。
  • ;secure: cookie将仅通过HTTPS传输。
  • ;HTTPOnly: 使cookie无法访问客户端JavaScript。
  • ;samesite=: 控制另一个域是否可以访问cookie。将其设置为lax(默认值,将cookie共享到当前域)、strict(阻止在从另一个域遵循链接时发送初始cookie)或none(无限制)。

示例:设置一个在10分钟后过期的状态cookie,并且可在当前域的任何路径中使用:

<code class="language-javascript">localStorage.setItem('value1', 123);
localStorage.setItem('value2', 'abc');
localStorage.setItem('state', JSON.stringify({ a:1, b:2, c:3 }));</code>

document.cookie返回一个包含每个名称和值对的字符串,它们用分号分隔。例如:

<code class="language-javascript">const state = JSON.parse( localStorage.getItem('state') );</code>

下面的函数解析字符串并将其转换为包含名称-值对的对象。例如:

<code class="language-javascript">localStorage.removeItem('state')</code>

优点:

  • 在客户端和服务器之间保留状态的可靠方法
  • 仅限于域和(可选)路径
  • 使用max-age(秒)或Expires(日期)进行自动到期控制
  • 默认情况下在当前会话中使用(设置到期日期以使数据持久保存超过页面刷新和选项卡关闭)

缺点:

  • cookie经常被浏览器和插件阻止(它们通常转换为会话cookie,以便网站继续工作)
  • 笨拙的JavaScript实现(最好创建您自己的cookie处理程序或选择js-cookie之类的库)
  • 仅限字符串(需要序列化和反序列化)
  • 存储空间有限
  • cookie可以被第三方脚本检查,除非您限制访问
  • 被指责侵犯隐私(区域立法可能要求您显示非必要cookie的警告)
  • cookie数据附加到每个HTTP请求和响应中,这可能会影响性能(存储50Kb的cookie数据,然后请求十个1字节的文件,将产生一百万字节的带宽)

除非没有可行的替代方案,否则避免使用cookie。

  1. window.name

指标 说明 容量变化,但应该可以容纳几兆字节读取/写入速度快持久性会话数据保留到选项卡关闭为止window.name属性设置和获取窗口浏览上下文的名称。您可以设置一个在浏览器刷新或链接到其他位置并单击后退之间持久存在的单个字符串值。例如:

<code class="language-javascript">const
  a = 1,
  b = 'two',
  state = {
    msg:  'Hello',
    name: 'Craig'
  };</code>

使用以下方法检查值:

<code class="language-javascript">// 定位<main>元素
</main>const main = document.querySelector('main');

// 存储值
main.dataset.value1 = 1;
main.dataset.state = JSON.stringify({ a:1, b:2 });

// 检索值
console.log( main.dataset.value1 ); // "1"
console.log( JSON.parse(main.dataset.state).a ); // 1</code>

优点:

  • 易于使用
  • 可用于仅限会话的数据

缺点:

  • 仅限字符串:需要序列化和反序列化
  • 其他域中的页面可以读取、修改或删除数据(切勿将其用于敏感信息)

window.name从未设计用于数据存储。这是一个技巧,并且有更好的选择

  1. WebSQL

指标 说明 容量每个域5MB读取/写入速度缓慢持久性数据保留到被清除为止WebSQL是将类似SQL的数据库存储引入浏览器的尝试。示例代码:

<code class="language-javascript">localStorage.setItem('value1', 123);
localStorage.setItem('value2', 'abc');
localStorage.setItem('state', JSON.stringify({ a:1, b:2, c:3 }));</code>

Chrome和某些版本的Safari支持这项技术,但Mozilla和Microsoft反对它,转而支持IndexedDB。

优点:

  • 专为强大的客户端数据存储和访问而设计
  • 服务器端开发人员经常使用的熟悉的SQL语法

缺点:

  • 浏览器支持有限且存在错误
  • 浏览器之间的SQL语法不一致
  • 异步但笨拙的基于回调的API
  • 性能差

不要使用WebSQL!自2010年规范被弃用以来,它一直不是一个可行的选择。

仔细检查存储

Storage API可以检查Web存储、IndexedDB和缓存API可用的空间。除Safari和IE之外的所有浏览器都支持基于Promise的API,该API提供.estimate()方法来计算配额(域可用的空间)和使用情况(已使用的空间)。例如:

<code class="language-javascript">const state = JSON.parse( localStorage.getItem('state') );</code>

还有另外两种异步方法可用:

  • .persist():如果站点有权存储持久性数据,则返回true,
  • .persisted():如果站点已存储持久性数据,则返回true。

浏览器开发者工具(在Firefox中名为Storage)中的应用程序面板允许您查看、修改和清除localStorage、sessionStorage、IndexedDB、WebSQL、cookie和缓存存储。

您还可以通过单击开发者工具的“网络”面板中的任何项目来检查HTTP请求和响应标头中发送的cookie数据。

存储大杂烩

这些存储解决方案都不完美,您需要在复杂的Web应用程序中采用多种解决方案。这意味着学习更多API。但是,在每种情况下都有选择是一件好事——当然,假设您可以选择合适的选项!

关于本地存储替代方案的常见问题

我可以用什么代替本地存储?

在寻找Web开发中本地存储的替代方案时,可以考虑会话存储、cookie和IndexedDB等选项。会话存储为页面会话期间提供临时存储,而cookie是与每个HTTP请求一起发送的小型数据片段,可用于会话管理和存储有限的数据。IndexedDB为在客户端存储结构化数据提供更强大的解决方案,使其适合需要异步数据检索的应用程序。 对于更广泛的数据存储或当安全性和持久性至关重要时,服务器端存储解决方案(如MySQL、PostgreSQL、MongoDB)或基于云的数据库(如Firebase、AWS DynamoDB或Google Cloud Firestore)可能更可取。此外,一些客户端框架提供自己的状态管理解决方案,而服务工作者可以缓存数据和资产以实现离线功能,使其适合渐进式Web应用程序 (PWA)。

什么时候不应该使用本地存储?

本地存储是一种通用的客户端存储解决方案,但在某些情况下,它可能不是最合适的选择。首先,本地存储不适合存储敏感或机密信息,因为它缺乏加密或安全措施,使其容易受到未经授权的访问。密码或个人身份等关键数据应使用强大的安全协议安全地存储在服务器端。 其次,本地存储的容量有限,每个域通常约为5-10 MB。它不适合需要处理大量数据的应用程序。在这种情况下,应考虑服务器端数据库或更强大的客户端选项(如IndexedDB)来容纳更大的数据集。 最后,本地存储可能会导致性能问题,尤其是在处理大量数据集时,因为它同步运行并且可能会阻塞主线程。对于性能关键型应用程序,可以使用异步存储解决方案(如IndexedDB)或实现内存缓存来维持流畅的用户体验。 总而言之,虽然本地存储对于轻量级、非敏感的数据存储很有价值,但必须评估项目的具体要求。对于敏感信息、大型数据集或性能关键型应用程序,应探索替代存储解决方案,以确保数据安全、可扩展性和最佳用户体验。

localStorage和sessionStorage哪个更好?

localStorage和sessionStorage的选择主要取决于您所需的数据持久性持续时间和您的具体用例。 当您需要数据在浏览器会话之间持久保存时,localStorage是更好的选择。它适合存储用户偏好、设置或缓存资源等数据,即使用户关闭浏览器并在稍后返回网站,这些数据也应保留给用户。它的持久性和更大的存储容量使其非常适合需要长期数据保留的场景。 另一方面,sessionStorage非常适合仅在当前页面会话期间可用的数据。当用户关闭选项卡或浏览器时,数据会自动清除,从而确保隐私并降低无意中存储不必要信息的风险。这使其非常适合管理临时数据,例如表单数据、购物车内容或单个用户交互中的状态管理。

什么是客户端数据库?

客户端数据库,也称为前端数据库,是一种驻留在Web应用程序客户端(通常在用户的Web浏览器中)并在此运行的数据库。它用于在客户端设备上存储和管理数据,允许Web应用程序离线工作,减少服务器负载,并通过最大限度地减少对频繁服务器请求的需求来改善用户体验。客户端数据库通常用于Web开发中,以便直接在用户的设备上存储和检索数据。 客户端数据库最常见的示例之一是IndexedDB,这是一个低级JavaScript API,它提供了一个结构化数据库,用于在Web浏览器中存储大量数据。IndexedDB允许开发人员创建、读取、更新和删除数据,使其适合需要离线存储和管理大量信息的应用程序。 客户端数据库的其他示例包括用于存储少量数据的Web存储(localStorage和sessionStorage),以及在JavaScript中实现的各种内存数据库,用于在用户会话期间进行临时数据存储。 客户端数据库对于渐进式Web应用程序 (PWA) 等Web应用程序特别有用,在这些应用程序中,即使用户离线或互联网连接有限,也需要保持功能。它们通过提供在用户设备上本地存储数据的机制来补充服务器端数据库,从而减少延迟并增强用户体验。

客户端存储有哪些不同类型?

Web开发中的客户端存储有多种形式,每种形式都有其自身的特性和用例。 一种常见的类型是Web存储,其中包括localStorage和sessionStorage。localStorage适合存储需要跨浏览器会话持久保存的小量数据,使其适用于用户偏好或设置。相反,sessionStorage是会话受限的,仅在单个页面会话期间存储数据,使其非常适合临时数据,例如用户与网页交互期间所需的购物车内容或表单数据。 另一种选择是IndexedDB,这是一种更高级的客户端数据库系统。IndexedDB提供结构化存储,用于在用户的设备上管理大量数据。它支持异步数据检索、索引、事务等等,使其非常适合需要复杂数据处理和离线功能(如渐进式Web应用程序 (PWA))的应用程序。 此外,cookie是可以存储在客户端设备上并与每个HTTP请求一起发送到服务器的小型数据片段。虽然如今不太常用于一般数据存储,但cookie仍然可用于会话管理、用户身份验证和跟踪用户偏好等任务。 每种类型的客户端存储都有其优缺点,选择取决于您的具体要求,例如数据大小、持久性需求和用例。

以上是10个客户端存储选项以及何时使用它们的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn