AI 文章摘要
XinruiGPT
加载中...
此内容根据文章生成,并未经过人工审核,仅用于文章内容的解释与总结

前言

最近魔改了一下主题,将首页右侧卡片改成了CMD打字机的效果,但是网站啊又是pjax加载的,所以每次访问文章再返回首页进度就会重置。

所以就想要用浏览器的localStorage功能来存储进度。当然一切还是靠AI的帮助。

什么是localStorage

localStorage 是 Web Storage API 的一部分,提供了在浏览器中存储键值对数据的能力。与 sessionStorage 不同,localStorage 中的数据没有过期时间,即使关闭浏览器后重新打开,数据依然存在。

主要特点

  • 持久化存储:数据保存在浏览器本地,关闭标签页或浏览器后仍然存在
  • 同源策略:只有相同协议、域名和端口的页面才能访问相同的数据
  • 容量较大:一般支持 5-10MB 的存储空间(因浏览器而异)
  • 仅支持字符串:只能存储字符串类型的数据,对象需要序列化

基本使用方法

存储数据

1
2
3
4
5
6
7
8
9
10
// 存储字符串
localStorage.setItem('username', '张三');

// 存储对象(需要序列化)
const user = { name: '张三', age: 25 };
localStorage.setItem('user', JSON.stringify(user));

// 存储数组
const todos = ['任务1', '任务2', '任务3'];
localStorage.setItem('todos', JSON.stringify(todos));

读取数据

1
2
3
4
5
6
7
8
9
10
11
// 读取字符串
const username = localStorage.getItem('username');
console.log(username); // 输出: 张三

// 读取对象(需要反序列化)
const user = JSON.parse(localStorage.getItem('user'));
console.log(user.name); // 输出: 张三

// 读取数组
const todos = JSON.parse(localStorage.getItem('todos'));
console.log(todos); // 输出: ['任务1', '任务2', '任务3']

删除数据

1
2
3
4
5
// 删除单个键值
localStorage.removeItem('username');

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

检查数据是否存在

1
2
3
4
5
6
// 检查键是否存在
if (localStorage.getItem('username')) {
console.log('用户名已存在');
} else {
console.log('用户名不存在');
}

实际应用场景

1. 用户偏好设置

1
2
3
4
5
6
7
8
9
10
11
12
13
// 保存主题偏好
function saveThemePreference(theme) {
localStorage.setItem('theme', theme);
}

// 读取主题偏好
function getThemePreference() {
return localStorage.getItem('theme') || 'light';
}

// 应用主题
const currentTheme = getThemePreference();
document.body.className = currentTheme;

2. 表单数据自动保存

1
2
3
4
5
6
7
8
9
10
11
12
13
// 监听输入变化,自动保存
const formInputs = document.querySelectorAll('input, textarea');
formInputs.forEach(input => {
input.addEventListener('input', function() {
localStorage.setItem(`form_${this.name}`, this.value);
});

// 页面加载时恢复数据
const savedValue = localStorage.getItem(`form_${input.name}`);
if (savedValue) {
input.value = savedValue;
}
});

3. 记住用户操作状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 保存侧边栏展开状态
function saveSidebarState(isCollapsed) {
localStorage.setItem('sidebar_collapsed', isCollapsed);
}

// 读取侧边栏状态
function getSidebarState() {
return localStorage.getItem('sidebar_collapsed') === 'true';
}

// 应用侧边栏状态
const sidebarCollapsed = getSidebarState();
if (sidebarCollapsed) {
document.querySelector('.sidebar').classList.add('collapsed');
}

4. 数据缓存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 缓存API响应数据
async function fetchDataWithCache(url) {
const cacheKey = `cache_${url}`;
const cachedData = localStorage.getItem(cacheKey);

if (cachedData) {
const { data, timestamp } = JSON.parse(cachedData);
const cacheAge = Date.now() - timestamp;

// 如果缓存时间小于1小时,使用缓存数据
if (cacheAge < 60 * 60 * 1000) {
return data;
}
}

// 获取新数据并缓存
const response = await fetch(url);
const data = await response.json();

localStorage.setItem(cacheKey, JSON.stringify({
data: data,
timestamp: Date.now()
}));

return data;
}

注意事项和最佳实践

1. 错误处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function safeLocalStorageGet(key) {
try {
return localStorage.getItem(key);
} catch (e) {
console.warn('localStorage 读取失败:', e);
return null;
}
}

function safeLocalStorageSet(key, value) {
try {
localStorage.setItem(key, value);
return true;
} catch (e) {
console.warn('localStorage 写入失败:', e);
return false;
}
}

2. 存储空间检查

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function checkLocalStorageSpace() {
try {
const testKey = '__storage_test__';
localStorage.setItem(testKey, 'test');
localStorage.removeItem(testKey);
return true;
} catch (e) {
return e instanceof DOMException && (
e.code === 22 || // Chrome
e.code === 1014 || // Firefox
e.name === 'QuotaExceededError' || // Safari
e.name === 'NS_ERROR_DOM_QUOTA_REACHED'
);
}
}

3. 数据版本管理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 存储带版本号的数据
function saveVersionedData(key, data, version = '1.0') {
const storageData = {
version: version,
data: data,
timestamp: Date.now()
};
localStorage.setItem(key, JSON.stringify(storageData));
}

// 读取带版本号的数据
function loadVersionedData(key, currentVersion = '1.0') {
const saved = localStorage.getItem(key);
if (!saved) return null;

try {
const parsed = JSON.parse(saved);
if (parsed.version === currentVersion) {
return parsed.data;
}
// 版本不匹配,删除旧数据
localStorage.removeItem(key);
return null;
} catch (e) {
localStorage.removeItem(key);
return null;
}
}

4. 隐私和安全考虑

  • 不要存储敏感信息:如密码、token、个人身份信息等
  • 数据加密:如果必须存储敏感数据,考虑使用加密
  • 同源策略:注意不同子域名间的数据隔离
  • 用户同意:在存储用户数据前获得明确同意

浏览器兼容性

浏览器 最低版本 备注
Chrome 4 完全支持
Firefox 3.5 完全支持
Safari 4 完全支持
IE 8 部分支持,需要 polyfill
Edge 12 完全支持

总结

localStorage 是一个简单但功能强大的浏览器存储解决方案,适用于各种需要持久化存储的场景。通过合理使用 localStorage,可以显著提升用户体验,减少不必要的服务器请求,实现离线功能等。

在实际应用中,要注意错误处理、存储限制和数据安全,确保为用户提供可靠的服务。