HTML5 离线存储是指通过 Web Storage API 提供的一种在客户端本地存储数据的机制,主要有两种方式:localStoragesessionStorage。与传统的 Cookie 相比,Web Storage 提供了更大容量、灵活性,并且数据不会随着 HTTP 请求自动发送到服务器,这可以优化性能和安全性。此外,HTML5 还支持 离线应用缓存(Application Cache)IndexedDB,用于更加复杂的数据存储需求和离线应用。

工作原理

HTML5 的离线存储主要通过以下几个机制来实现数据存储和访问:

  1. localStorage:一种持久性存储机制,数据存储在用户的浏览器中,即使关闭浏览器或重新加载页面,数据也不会丢失,除非明确被删除。其特点是跨页面、跨会话存储数据。
  2. sessionStorage:会话级别的存储机制,只在当前页面的会话期间有效。当会话结束或浏览器窗口关闭时,数据会自动删除。其特点是只能在当前窗口或标签页中存储数据,不能跨窗口或标签页共享。
  3. Application Cache(已被 Service Worker 替代):允许开发者将网站的某些资源缓存到本地,使得用户即使在离线的情况下也能访问特定页面。虽然该机制已被弃用,但它曾经是实现离线访问的核心。
  4. IndexedDB:一种更为复杂的浏览器内置数据库,支持存储结构化数据,如对象和文件。它适用于更大规模的数据存储需求,并且允许通过索引进行高效的查询和数据操作。

使用方式

1. localStorage

  • 特点:持久性存储,浏览器关闭后数据依然存在,除非手动清除。
  • 使用方式
// 存储数据
localStorage.setItem('key', 'value');

// 获取数据
let value = localStorage.getItem('key');

// 删除数据
localStorage.removeItem('key');

// 清空所有 localStorage
localStorage.clear();

2. sessionStorage

  • 特点:仅在当前会话期间有效,浏览器关闭或页面重新加载后数据会被清除。
  • 使用方式
// 存储数据
sessionStorage.setItem('sessionKey', 'sessionValue');

// 获取数据
let sessionValue = sessionStorage.getItem('sessionKey');

// 删除数据
sessionStorage.removeItem('sessionKey');

// 清空所有 sessionStorage
sessionStorage.clear();

3. IndexedDB

  • 特点:适合存储大量的结构化数据,支持异步 API 和事务。
  • 使用方式: IndexedDB 的使用较为复杂,通常涉及打开数据库、创建事务、存储和检索数据等操作。一个简单的示例如下:
let request = indexedDB.open('myDatabase', 1);

request.onupgradeneeded = function(event) {
  let db = event.target.result;
  let objectStore = db.createObjectStore('myObjectStore', { keyPath: 'id' });
};

request.onsuccess = function(event) {
  let db = event.target.result;
  let transaction = db.transaction(['myObjectStore'], 'readwrite');
  let objectStore = transaction.objectStore('myObjectStore');
  objectStore.add({ id: 1, name: 'John Doe' });
};

4. Application Cache(弃用)

  • 特点:通过 manifest 文件指定需要缓存的资源,允许在离线时访问应用。
  • 使用方式: 在 HTML 文档中指定 manifest 文件:
<html manifest="app.manifest">

然后在 app.manifest 文件中列出需要缓存的资源:

CACHE MANIFEST
# 版本 1.0

CACHE:
index.html
styles.css
script.js

NETWORK:
*

注意:由于该技术已被弃用,开发者应使用更先进的 Service Workers 实现离线应用缓存。

使用场景

1. localStorage 使用场景

  • 持久化用户偏好设置:例如主题、语言、字体大小等,用户下次访问时可以加载之前的设置。
  • 保存购物车内容:用户可以关闭浏览器再重新打开,购物车中的商品信息依然存在。
  • 表单数据缓存:在用户填写表单时,如果页面刷新或浏览器意外关闭,可以在用户下次访问时恢复填写的内容。

2. sessionStorage 使用场景

  • 临时保存多步骤表单数据:适合单次会话中暂时保存数据,比如多步骤表单的中间数据。
  • 页面跳转间的数据传递:在不同页面之间传递一些临时数据,不需要持久化保存。

3. IndexedDB 使用场景

  • 大型离线应用:例如,离线的待办事项管理器、笔记应用等,需要保存大量用户数据,并且需要复杂的查询和排序功能。
  • 存储结构化数据:适用于存储 JSON、文件等结构化数据,或者通过索引进行高效的查询。

4. Application Cache(已弃用,使用 Service Worker 替代)

  • 离线访问:在没有网络连接的情况下允许用户访问某些页面或资源。

优缺点

优点:

  1. 容量大:与 Cookie 相比,localStoragesessionStorage 提供了 5-10 MB 的存储空间,而 Cookie 仅有 4 KB。
  2. 高效:Web Storage 不会随着每个请求发送到服务器,因此减轻了服务器的负担,并提高了页面加载速度。
  3. 安全:数据存储在本地,不会暴露在每次请求中,降低了某些安全风险。
  4. API 简单:提供简单易用的 API 进行存储、读取和删除操作。

缺点:

  1. 不支持旧版浏览器:较老的浏览器不支持 Web Storage(尤其是 IE7 及更早版本)。
  2. 安全性:如果页面存在 XSS 漏洞,攻击者可以利用 Web Storage 来存取敏感数据。
  3. 同步特性:localStorage 和 sessionStorage 都是同步操作,可能会在数据量大时阻塞主线程。

常见考点

1. localStorage 与 sessionStorage 的区别

  • 存储时长localStorage 是持久存储,关闭浏览器后数据依然存在;sessionStorage 是会话级别存储,关闭浏览器或标签页时数据会被清除。
  • 存储范围localStorage 可以在多个页面共享数据;sessionStorage 只能在当前标签页或窗口中使用,不能跨页面或标签页共享。
  • 存储容量:两者存储容量一般都在 5-10 MB 之间,但具体由浏览器厂商决定。
  • 容量限制:Cookie 容量限制较小,通常为 4 KB;Web Storage 容量更大,通常为 5-10 MB。
  • 通信特性:Cookie 随每次 HTTP 请求发送给服务器,而 Web Storage 数据仅存储在本地,不会自动随请求发送,提升了性能。
  • 作用域和存储方式:Cookie 可设置过期时间和作用域(域名和路径),而 Web Storage 仅限于同源策略下的客户端存储。

3. Web Storage 的 API

  • 存储数据localStorage.setItem(key, value)sessionStorage.setItem(key, value)
  • 读取数据localStorage.getItem(key)sessionStorage.getItem(key)
  • 删除数据localStorage.removeItem(key)sessionStorage.removeItem(key)
  • 清空存储localStorage.clear()sessionStorage.clear()
  • 考察点可能涉及 API 的具体用法及如何操作存储的数据。

4. Web Storage 的数据存储格式

  • 数据只能以 字符串 的形式存储,存储复杂数据结构(如对象、数组)时,通常需要使用 JSON.stringify()JSON.parse() 进行序列化和反序列化。
  • 考题可能涉及如何将对象或数组存储在 Web Storage 中。

5. Web Storage 的安全性

  • XSS 攻击:Web Storage 可以存储大量数据,但如果页面存在 XSS(跨站脚本)漏洞,恶意脚本可能会读取存储的数据。因此,考察点可能涉及如何防止 XSS 攻击,如输入数据的转义和编码等。
  • 权限控制:如何确保 Web Storage 数据只在特定域名或路径下访问,防止数据泄露。

6. 浏览器支持及兼容性

  • 不同浏览器对 Web Storage 的支持情况如何?考察点可能包括如何检测浏览器是否支持 localStoragesessionStorage,并提供兼容方案。
  • 例如,如何检查浏览器是否支持 Web Storage:
if (typeof(Storage) !== "undefined") {
    // 支持 Web Storage
} else {
    // 不支持
}

7. Web Storage 的存储容量限制

  • 不同浏览器对 localStoragesessionStorage 的容量限制有所不同,考察点可能包括如何处理存储容量超限的情况,以及如何处理存储异常(如 quota exceeded error)。
  • 如何在使用 Web Storage 时确保不超出存储限制。

8. 如何删除 localStorage/sessionStorage 的数据?

  • 考题可能会询问如何删除 Web Storage 中的数据,特别是如何删除单个键值对或清除所有存储的数据。

9. Web Storage 的使用场景

  • 考察点可能涉及根据不同需求选择 localStoragesessionStorage。例如,何时适合使用持久化存储(如用户偏好、购物车内容),何时适合使用会话级存储(如表单的中间状态)。
  • 需要能够根据业务场景灵活运用 Web Storage。

10. 数据持久性和生命周期

  • 如何解释 localStorage 数据的持久性?即使刷新页面或关闭浏览器后,数据仍然存在。
  • sessionStorage 的生命周期管理,如何控制数据的会话级存储。

11. IndexedDB 与 Web Storage 的区别

  • 面试中可能会比较 IndexedDB 和 Web Storage(localStoragesessionStorage)之间的区别,如 IndexedDB 更适合存储大数据或结构化数据,Web Storage 适合存储简单键值对数据。
  • 何时选择使用 IndexedDB 而不是 localStorage

12. Service Workers 与 Web Storage 的配合使用

  • 如何结合使用 Service WorkerslocalStorage 来实现离线应用的数据持久化。
  • 考题可能涉及如何处理离线数据存储、数据同步等。

13. localStorage 的跨域限制

  • 考察 localStoragesessionStorage 是否能在不同域名或不同子域间共享数据,以及同源策略的应用。
  • 如何在跨域情况下共享数据。

14. 如何清除用户数据

  • 如果用户希望清除所有的存储数据,除了删除浏览器缓存外,还有哪些方式可以删除 localStoragesessionStorage 的数据?
  • 是否可以通过代码控制 Web Storage 的清空操作。

15. Web Storage 可能带来的问题

  • 可能会考察 Web Storage 的潜在问题,例如:存储容量的限制、数据持久化的安全性问题、跨域访问的限制等。