一、核心概念与应用场景

localStoragesessionStorage是HTML5提供的客户端存储方案,用于在浏览器中保存键值对数据,替代传统Cookie的局限性(存储容量小、每次请求携带)。两者均遵循同源策略(仅同一协议、域名、端口下可访问),但在存储周期和作用域上存在关键差异:

特性 localStorage sessionStorage
存储周期 永久存储(除非手动删除) 仅当前会话(标签页关闭后清除)
作用域 同源所有标签页共享 仅当前标签页私有
存储容量 约5MB 约5MB
数据类型 仅支持字符串(需手动序列化) 仅支持字符串(需手动序列化)

典型应用场景

  • localStorage:保存用户偏好设置(如主题、字体大小)、离线数据缓存。
  • sessionStorage:临时存储表单数据(如多步骤表单)、会话令牌(登录状态)。

二、语法与核心API

2.1 基础操作方法

API 作用 示例
setItem(key, value) 存储数据(覆盖已有键) localStorage.setItem('theme', 'dark')
getItem(key) 获取数据(不存在返回null const theme = localStorage.getItem('theme')
removeItem(key) 删除指定键数据 localStorage.removeItem('theme')
clear() 清空所有存储数据 sessionStorage.clear()
key(index) 获取指定索引的键名 const firstKey = localStorage.key(0)

2.2 数据类型处理

由于存储数据仅支持字符串,非字符串类型(对象、数组等)需通过JSON序列化/反序列化:

存储对象/数组:

// 存储用户信息对象
const user = { name: '张三', age: 25, isVIP: true };
localStorage.setItem('user', JSON.stringify(user)); // 序列化

// 读取并解析
const savedUser = JSON.parse(localStorage.getItem('user'));
console.log(savedUser.name); // 输出:"张三"

存储数字/布尔值:

// 存储数字(自动转为字符串)
localStorage.setItem('score', 95); 
console.log(typeof localStorage.getItem('score')); // 输出:"string"

// 读取时需手动转换类型
const score = Number(localStorage.getItem('score')); 

三、实战示例

3.1 保存用户主题偏好

<!DOCTYPE html>
<html>
<head>
  <title>主题切换示例</title>
  <style>
    /* 默认浅色主题 */
    .light { background: #fff; color: #333; }
    /* 深色主题 */
    .dark { background: #333; color: #fff; }
  </style>
</head>
<body class="light">
  <button onclick="switchTheme('light')">浅色主题</button>
  <button onclick="switchTheme('dark')">深色主题</button>

  <script>
    // 页面加载时读取保存的主题
    window.onload = () => {
      const savedTheme = localStorage.getItem('theme');
      if (savedTheme) {
        document.body.className = savedTheme;
      }
    };

    // 切换主题并保存
    function switchTheme(theme) {
      document.body.className = theme;
      localStorage.setItem('theme', theme); // 持久化保存
    }
  </script>
</body>
</html>

3.2 临时存储表单数据(sessionStorage)

<!-- 多步骤表单第一步 -->
<form id="step1">
  <input type="text" name="username" placeholder="用户名" required>
  <button type="button" onclick="saveStep1()">下一步</button>
</form>

<script>
  function saveStep1() {
    const form = document.getElementById('step1');
    const formData = new FormData(form);
    const userData = { username: formData.get('username') };
    
    // 临时存储到sessionStorage
    sessionStorage.setItem('step1Data', JSON.stringify(userData));
    window.location.href = 'step2.html'; // 跳转至第二步
  }
</script>

<!-- 多步骤表单第二步(step2.html) -->
<script>
  // 读取第一步数据
  const step1Data = JSON.parse(sessionStorage.getItem('step1Data'));
  console.log('第一步用户名:', step1Data.username);
</script>

四、注意事项与兼容性

4.1 常见问题与解决方案

  1. 数据类型丢失

    • ❌ 错误:直接存储对象 localStorage.setItem('user', {name: '张三'})(结果为 "[object Object]"
    • ✅ 正确:使用 JSON.stringify()JSON.parse() 处理非字符串数据。
  2. 存储容量限制

    • 单条数据过大或总容量超过5MB时会抛出错误,建议:
      • 拆分大型数据为多条存储;
      • 敏感/大量数据使用服务器存储(如数据库)。
  3. 隐私模式限制

    • 部分浏览器在隐私模式下禁用localStorage,需添加异常处理:
      try {
        localStorage.setItem('test', '1');
      } catch (e) {
        console.error('存储失败:', e.message); // 如"QuotaExceededError"
      }
      

4.2 浏览器兼容性

  • 支持情况:所有现代浏览器(Chrome 4+、Firefox 3.5+、Edge 12+、Safari 4+)
  • IE兼容性:IE8及以上支持,但需注意:
    • IE8/9不支持localStorage.clear()清空单个键,需遍历删除;
    • 不支持JSON.parse()解析复杂对象(需引入json2.js polyfill)。

五、自测题

  1. 以下关于localStoragesessionStorage的说法错误的是:
    A. 两者均遵循同源策略
    B. sessionStorage在新标签页中可共享数据
    C. 存储数据均需手动序列化对象

  2. 如何实现localStorage中存储数组并读取?

    // 存储数组
    const arr = [1, 2, 3];
    _______________________; 
    
    // 读取数组
    const savedArr = _______________________;
    
  3. 简述使用localStorage保存用户登录状态的风险及改进方案。

答案

  1. B(sessionStorage仅当前标签页私有,新标签页无法共享)
  2. localStorage.setItem('arr', JSON.stringify(arr))JSON.parse(localStorage.getItem('arr'))
  3. 风险:数据永久存储易被盗取;改进:存储加密令牌+定期刷新,敏感操作需重新验证。