惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

罗磊的独立博客
G
Google Developers Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
腾讯CDC
有赞技术团队
有赞技术团队
Vercel News
Vercel News
MongoDB | Blog
MongoDB | Blog
M
MIT News - Artificial intelligence
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
B
Blog RSS Feed
I
InfoQ
Blog — PlanetScale
Blog — PlanetScale
博客园_首页
The Cloudflare Blog
B
Blog
C
Check Point Blog
Stack Overflow Blog
Stack Overflow Blog
IT之家
IT之家
U
Unit 42
D
Docker
月光博客
月光博客
aimingoo的专栏
aimingoo的专栏
博客园 - Franky
A
About on SuperTechFans

新锐博客

vscode连接cnb并推送仓库 - 新锐博客 twikoo不用token查询文章浏览量 - 新锐博客 基于Astro构建的支持对话与生图的Web应用 - 新锐博客 deepseek-v4-flash-0731使用体验 - 新锐博客 基元律动免费送68元额度 - 新锐博客 Linux更换软件源 - 新锐博客 华为鸿蒙7.0花粉beta版发布 - 新锐博客 使用测速脚本测一下服务器带宽 - 新锐博客 trae告别白嫖时代,auto也需排队了 - 新锐博客 流量不够用?大流量卡免费领 - 新锐博客 推荐一个免费在线图片处理网站 - 新锐博客 AI清理C盘的优缺点 - 新锐博客 twikoo不算bug的bug - 新锐博客 最近网站的一些变动 - 新锐博客 腾讯EO开始发多余套餐啦!速领 - 新锐博客 hi168停止对个人用户的运营 - 新锐博客 哪吒监控曝高危漏洞,请尽快升级 - 新锐博客 IndexDB实现大文件下载的思路 - 新锐博客 鱼鱼api使用教程 - 新锐博客 服务器安装Dokploy替代vercel - 新锐博客 对于近几年的电视剧的无力吐槽 - 新锐博客 关于网站被攻击的后续 - 新锐博客 使用sessionStorage给音乐播放进度存储 - 新锐博客 修复了一些bug,网站基本上趋于稳定了 - 新锐博客 AI模型掺水?如何辨别真假? - 新锐博客 感谢一九云给我防住了攻击 - 新锐博客 对一些新手使用AI编程的建议 - 新锐博客 Edgeone标记过期和直接删除有何区别? - 新锐博客 用Navigation Timing API给博客添加上加载时间 - 新锐博客 使用 Astro 自建博客,从零开始鏖战 14 小时 - 新锐博客
使用浏览器的localStorage功能存储数据 - 新锐博客
莫忘 · 2026-02-25 · via 新锐博客

前言

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

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

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

主要特点

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

基本使用方法

存储数据

// 存储字符串
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));

读取数据

// 读取字符串
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']

删除数据

// 删除单个键值
localStorage.removeItem('username');

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

检查数据是否存在

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

实际应用场景

1. 用户偏好设置

// 保存主题偏好
function saveThemePreference(theme) {
  localStorage.setItem('theme', theme);
}

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

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

2. 表单数据自动保存

// 监听输入变化,自动保存
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. 记住用户操作状态

// 保存侧边栏展开状态
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. 数据缓存

// 缓存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. 错误处理

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. 存储空间检查

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. 数据版本管理

// 存储带版本号的数据
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、个人身份信息等
  • 数据加密:如果必须存储敏感数据,考虑使用加密
  • 同源策略:注意不同子域名间的数据隔离
  • 用户同意:在存储用户数据前获得明确同意

浏览器兼容性

浏览器最低版本备注
Chrome4完全支持
Firefox3.5完全支持
Safari4完全支持
IE8部分支持,需要 polyfill
Edge12完全支持

总结

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

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

莫忘

君子喻以义,小人喻以利

本文是原创文章,采用 CC BY-NC-SA 4.0 协议,完整转载请注明来自 新锐博客