HTML5 - Web 存储
HTML5 - Web Storage
Section titled “HTML5 - Web Storage”HTML5 Web Storage(网络存储)提供了机制,使 Web 应用程序能够在用户浏览器内本地存储数据。这允许应用程序保留用户偏好设置、离线数据,并通过缓存资源提高性能。
Web Storage 相对于传统 cookie 具有优势:
- 更大的存储容量:浏览器通常为每个源(origin)分配 5-10MB 的 Web Storage 空间,远超 cookie 的 4KB 限制。
- 不随 HTTP 请求发送:存储的数据不会随每个 HTTP 请求自动发送,从而减少网络开销并提高安全性。
- 客户端接口:提供一个简单的同步 JavaScript API,用于设置、检索和移除数据。
Web Storage 主要有两种类型:localStorage 和 sessionStorage。
所有现代浏览器,包括桌面和移动版本,都支持 Web Storage。
Session Storage (sessionStorage)
Section titled “Session Storage (sessionStorage)”sessionStorage 为每个给定的源(origin)维护一个单独的存储区域,该区域的可用性持续整个页面会话(只要浏览器标签页或窗口保持打开,包括页面重载和恢复)。
存储在 sessionStorage 中的数据特定于创建它的窗口或标签页。如果用户在新的标签页或窗口中打开同一个网页,会创建一个新的会话和单独的存储区域。
- 在多步表单中存储临时用户输入。
- 跟踪单个会话中的用户活动(例如,查看过的项目)。
- 维护特定于单个浏览器标签页的应用程序状态。
以下代码在同一会话中每次页面加载时增加一个计数器:
<!DOCTYPE html><html><head> <title>Session Storage Example</title></head><body> <h1>Session Storage Page Counter</h1> <p id="hitCount"></p>
<script> // 检查 sessionStorage 是否受支持 if (typeof(Storage) !== "undefined") { // 从 sessionStorage 中检索当前访问计数 let hits = sessionStorage.getItem('pageHits');
// 如果不存在,初始化为 1,否则增加 if (hits) { hits = Number(hits) + 1; } else { hits = 1; }
// 将更新后的计数存回 sessionStorage sessionStorage.setItem('pageHits', hits);
// 在页面上显示计数 document.getElementById('hitCount').textContent = `Page loads this session: ${hits}`; } else { document.getElementById('hitCount').textContent = 'Sorry, your browser does not support Web Storage.'; } </script>
<p>Refresh the page to increase the counter.</p> <p>Close the tab/window and reopen the page to reset the counter.</p></body></html>刷新页面以增加计数器。
关闭标签页/窗口并重新打开页面以重置计数器。
Local Storage (localStorage)
Section titled “Local Storage (localStorage)”localStorage 的功能与 sessionStorage 相同,但即使浏览器关闭并重新打开后也会保留。对于同一源(origin),数据在不同会话、标签页和窗口之间仍然可用,直到用户或 Web 应用程序明确清除为止。
- 存储用户偏好设置(例如,主题设置、语言选择)。
- 在不同的浏览器会话中保持用户登录状态(尽管更安全的方法通常涉及服务器端会话)。
- 缓存应用程序数据以供离线使用或加快启动速度。
此示例保存并检索用户的首选主题:
<!DOCTYPE html><html><head> <title>Local Storage Example</title> <style id="themeStyle"></style></head><body> <h1>Local Storage Theme Preference</h1>
<label for="themeSelect">Choose Theme:</label> <select id="themeSelect"> <option value="light">Light</option> <option value="dark">Dark</option> </select>
<script> const themeSelect = document.getElementById('themeSelect'); const themeStyle = document.getElementById('themeStyle');
function applyTheme(theme) { if (theme === 'dark') { themeStyle.textContent = 'body { background-color: #333; color: #eee; } select, label { color: #eee; }'; } else { themeStyle.textContent = 'body { background-color: #fff; color: #333; } select, label { color: #333; }'; } themeSelect.value = theme; }
function saveThemePreference(theme) { if (typeof(Storage) !== "undefined") { localStorage.setItem('userTheme', theme); } else { console.warn('localStorage not supported, cannot save theme preference.'); } }
// 在页面加载时加载保存的主题 if (typeof(Storage) !== "undefined") { const savedTheme = localStorage.getItem('userTheme') || 'light'; // 默认为浅色主题 applyTheme(savedTheme); } else { console.warn('localStorage not supported, using default theme.'); // localStorage 不受支持,使用默认主题。 applyTheme('light'); }
// 主题更改的事件监听器 themeSelect.addEventListener('change', (event) => { const selectedTheme = event.target.value; applyTheme(selectedTheme); saveThemePreference(selectedTheme); }); </script>
<p>Your theme preference will be saved even if you close the browser.</p></body></html>你的主题偏好设置将会被保存,即使你关闭浏览器。
Web Storage API 方法
Section titled “Web Storage API 方法”localStorage 和 sessionStorage 都共享相同的 API 方法:
setItem(key, value):添加或更新一个键值对(key-value pair)。key 和 value 都必须是字符串。getItem(key):检索与 key 关联的值。如果 key 不存在,则返回null。removeItem(key):移除与 key 关联的键值对。clear():移除该 origin 下的所有键值对。key(index):返回指定数字索引处的 key 名称。length:一个只读属性(read-only property),返回存储的键值对数量。
**重要提示:**Web Storage 只能存储字符串。如果你需要存储对象或数组,必须在保存前将它们序列化(例如,使用 JSON.stringify()),并在检索时反序列化(使用 JSON.parse())。
// 存储一个对象const userPrefs = { theme: 'dark', fontSize: 16 };localStorage.setItem('preferences', JSON.stringify(userPrefs));
// 检索对象const storedPrefsString = localStorage.getItem('preferences');const retrievedPrefs = storedPrefsString ? JSON.parse(storedPrefsString) : {};console.log(retrievedPrefs.theme); // 输出: dark限制和注意事项
Section titled “限制和注意事项”- **同步性:**API 操作是同步的,这意味着如果处理大量数据或慢速磁盘访问,调用可能会阻塞主浏览器线程。对于复杂或大规模存储,首选 IndexedDB。
- **仅限字符串:**如前所述,只能直接存储字符串。
- **存储限制:**虽然比 cookie 大,但 5-10MB 的限制对于某些应用程序仍然可能受限。
- **安全性:**数据存储在客户端,可以被运行在同一 origin 的任何脚本访问或修改。不要在 Web Storage 中存储敏感信息(例如密码或令牌)。
- **无查询功能:**Web Storage 是一个简单的键值存储。它缺乏 IndexedDB 等数据库中存在的索引或查询功能。
对于需要索引、事务或更大容量数据的更高级客户端存储需求,考虑使用 IndexedDB API。