JavaScript本地存储全解析:localStorage、sessionStorage、Cookie与IndexedDB用法及场景

作者:纸飞机

时间:2026-10-31

浏览:406

本文汇总JavaScript中四种本地存储方式:sessionStorage、localStorage、Cookie和IndexedDB。详细解析各API的操作方法、数据生命周期、容量限制及同源策略,并对比它们在标记用户、长期保存Token、会话管理及结构化大数据存储中的具体应用场景。

文章目录

在JavaScript开发中,本地存储机制允许网页在用户浏览器端保存数据,从而避免每次交互都向服务器传输冗余信息,实现跨会话的数据保留。目前前端主要采用四种本地存储方案:sessionStorage、localStorage、Cookie以及IndexedDB。

JavaScript提供了4种数据存储方案,具体分类如下:

  • sessionStorage
  • localStorage
  • Cookie
  • IndexedDB

一、JavaScript本地存储之 sessionStorage

sessionStorage 的数据生命周期仅限于当前会话,一旦页面关闭或浏览器窗口关闭,数据即被清除。这意味着该存储方式仅存在于窗口(页面)的活跃期间,窗口关闭后数据自动删除。

sessionStorage 提供以下操作方法:

  • setItem(key, value):用于设置数据
  • getItem(key):用于获取指定键的数据
  • removeItem(key):用于移除指定键的数据
  • clear():用于清除所有存储的数据

sessionStorage 使用示例如下:

// 添加数据
window.sessionStorage.setItem("name","李四")
window.sessionStorage.setItem("age",18)

// 获取数据
console.log(window.sessionStorage.getItem("name")) // 李四

// 清除某个数据
window.sessionStorage.removeItem("gender")

// 清空所有数据
window.sessionStorage.clear()

二、JavaScript本地存储之 localStorage

localStorage 是 HTML5 引入的技术,旨在用户浏览器中实现数据的长期持久化,直至用户手动删除。其操作接口与 sessionStorage 类似,均提供 setItem、getItem、removeItem 和 clear 方法,但关键区别在于 localStorage 存储的数据没有内置的过期时间。

localStorage 提供以下操作方法:

  • setItem(key, value):用于设置数据
  • getItem(key):用于获取指定键的数据
  • removeItem(key):用于移除指定键的数据
  • clear():用于清除所有存储的数据
// 存储数据
localStorage.setItem("name", "张三");
localStorage.setItem("age", 20);
localStorage.setItem("gender", "男");

// 获取数据
console.log(localStorage.getItem("name")); // 输出: 张三

// 删除数据
localStorage.removeItem("gender");

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

由于 localStorage 仅支持字符串存储,若需保存对象,必须先通过 JSON.stringify() 将其序列化为 JSON 字符串,读取时再通过 JSON.parse() 解析。此外,可通过添加时间戳和过期时间逻辑来手动实现数据失效机制。

Storage.prototype.setExpire = (key, value, expire) => {
	let obj = {
	data: value,
	time: Date.now(),
	expire: expire
	};
	//localStorage 设置的值不能为对象,转为json字符串
	localStorage.setItem(key, JSON.stringify(obj));
}

Storage.prototype.getExpire = key => {
    let val = localStorage.getItem(key);
    if (!val) {
        return val;
    }
    val = JSON.parse(val);
    if (Date.now() - val.time > val.expire) {
        localStorage.removeItem(key);
        return null;
    }
    return val.data;
}

//使用方法
localStorage.setExpire('userId','zhangsan',5000);
window.setInterval(()=>{
    console.log(localStorage.getExpire("userId"));
},1000)
  • 总结 localStorage 特性如下:
  • 持久化存储:即使窗口关闭,数据依然保留,除非用户手动删除。
  • 页面刷新后数据不丢失。
  • 存储容量一般限制在 5MB 左右。
  • 支持同一浏览器下的多窗口(多页面)共享数据。
  • 假设在同一个浏览器中打开同源的三个页面(如 .com/a.html、.com/b.html、.com/c.html),这三个窗口可以共享 localStorage 中的数据。
  • 以键值对形式保存数据。
  • 使用 localStorage.setItem(key, valueStr) 保存值,其中 valueStr 必须是字符串。若要存储对象,需先通过 JSON.stringify() 进行字符串序列化,取值时再通过 JSON.parse() 还原。
  • 通过键名获取对应的值。
  • 使用 value = localStorage.getItem(key) 获取值,若键不存在,则返回 null。
  • 受同源策略限制,不同源的页面无法相互访问 localStorage。
  • 例如,在浏览器中打开 www.baidu.com/index.html 存储了 localStorage 数据,此时打开 www.ali.com/index.html 无法访问该数据,因为两者不同源。
  • 操作 localStorage 时,会触发非当前页面的 storage 事件。
  • 当在 A 页面设置 localStorage 时,会触发其他同源页面的 storage 事件,便于监听状态变化并做出响应。例如,在登录页将登录成功标志 logSuc 存入 localStorage(localStorage.setItem('logSuc', true)),个人中心页面即可通过监听 storage 事件判断登录状态,并读取个人信息进行预加载。
  • 支持单个删除和全部删除,分别通过 removeItem(key) 和 clear() 方法实现。

三、JavaScript本地存储之 Cookie

  • Cookie 是存储在计算机文本文件中的数据,主要用于存储 Web 页面的用户信息。
  • Cookie 数据以键值对形式存在,每个键值对都包含过期时间。若未设置时间,浏览器关闭时 Cookie 即消失;用户也可手动清除 Cookie。
  • 每次 HTTP 请求都会携带 Cookie 到 HTTP 头中,若使用 Cookie 保存过多数据,可能引发性能问题。
  • Cookie 内存大小受限,通常每个域名下约为 4KB,每个域名大概能存储 50 个键值对。

通过访问 document.cookie 可对 Cookie 进行创建、修改与获取。默认情况下,Cookie 在浏览器关闭时删除。用户还可为 Cookie 的某个键值对添加过期时间;若设置新 Cookie 时某个 key 已存在,则会更新该 key 对应的值,否则新键值对会与现有数据共存。

// 设置cookie
document.cookie = "username=orochiz"
document.cookie = "age=20"

// 读取cookie
var msg = document.cookie
console.log(msg) // username=orochiz; age=20

// 添加过期时间(单位:天)
var d = new Date() // 当前时间 2019-9-25
var days = 3       // 3天
d.setDate(d.getDate() + days)
document.cookie = "username=orochiz;"+"expires="+d

// 删除cookie (给某个键值对设置过期的时间)
d.setDate(d.getDate() - 1)
console.log(document.cookie)

四、JavaScript本地存储之 IndexedDB

  • 前述存储方式均以字符串形式存储,若需求涉及大量结构化数据的存储,则应使用 IndexedDB。
  • IndexedDB 是一个真正的客户端数据库,其功能与服务端数据库类似,区别在于数据存储于客户端。
  • 既然具备数据库特性,其优点包括以下几点:
  • 储存量理论上没有上限。
  • 所有操作均为异步执行,相比 localStorage 的同步操作,性能更高,尤其在数据量较大时表现更优。
  • 原生支持存储 JavaScript 对象。
  • 作为数据库,它能执行数据库常见的操作。具体操作流程遵循数据库的一般规范,但为了适配客户端环境,部分步骤或程序逻辑可能进行了微调。
  • 实际操作包括建立连接、打开数据库、执行增删改查等操作。下面通过一个实例演示具体操作。
class DBOpration{
        constructor() {
            this.db = null
        }
        getType(val) {
            let type = typeof val == 'object'
            return type
        }
        // 打开数据库
        open(parm) {
            return new Promise((res, rej) => {
                let request = window.indexedDB.open(parm.dbName, parm.versions)
                request.onerror = function(event) {
                    console.log(event)
                    // 错误处理
                    rej()
                    console.log(' 打开数据库报错')
                }
                request.onsuccess = event => {
                    this.db = request.result
                    console.log('打开数据库成功')
                    res()
                    // 成功处理
                }
                // 数据库更新时的回调
                request.onupgradeneeded = event => {
                    this.db = event.target.result
                    this.createdDB(parm)
                }
            })
        }
        // 创建库表
        createdDB(parm) {
            console.log(parm)

            if (!this.db.objectStoreNames.contains(parm.objName)) {
                this.db.createObjectStore(parm.objName, {
                    keyPath: 'id'
                })
                // objectStore.createIndex("data", "data", { unique: false });
                // unique name可能会重复
            }
        }
        // 新增(不需要使用)
        async add(parm = { dbName, objName, param, response }) {
            await this.open(parm)
            // await this.upgrade(dbName);
            return new Promise((res, rej) => {
                let type = this.getType(parm.param)
                let type1 = this.getType(parm.response)
                let transaction = this.db.transaction([parm.objName], 'readwrite')
                let objectStore = transaction.objectStore(parm.objName)

                // 用户读取数据,参数是主键
                let request = objectStore.add({
                    id: type ? JSON.stringify(parm.param) : parm.param,
                    data: type1 ? JSON.stringify(parm.response) : parm.response
                })
                console.log(request)

                request.onsuccess = function(event) {
                    res(event)
                    console.log('数据写入成功')
                }

                request.onerror = function(event) {
                    rej()
                    console.log('数据写入失败')
                }
            })
        }
        // 读取库表数据
        async read(parm = { dbName, objName, param, response }) {
            await this.open(parm)

            return new Promise((res, rej) => {
                let type = this.getType(parm.param)

                var transaction = this.db.transaction([parm.objName])
                var objectStore = transaction.objectStore(parm.objName)
                // 用户读取数据,参数是主键
                var request = objectStore.get(type ? JSON.stringify(parm.param) : parm.param)

                request.onerror = function(event) {
                    console.log('事务失败')
                    rej()
                }

                request.onsuccess = function(event) {
                    if (request.result) {
                        let data = JSON.parse(request.result.data)
                        res(data)
                    } else {
                        res(request.result)
                        console.log('未获得数据记录')
                    }
                }
            })
        }
        // 修改库表数据,但是因为创建数据库时直接创建了库表,所以无论是添加还是修改都掉这个就可以了.
        async update(parm = { dbName, objName, param, response }) {
            await this.open(parm)

            return new Promise((res, rej) => {
                let type = this.getType(parm.param)
                let type1 = this.getType(parm.response)

                console.log(parm)
                var request = this.db
                    .transaction([parm.objName], 'readwrite')
                    .objectStore(parm.objName)
                    .put({
                        id: type ? JSON.stringify(parm.param) : parm.param,
                        data: type1 ? JSON.stringify(parm.response) : parm.response
                    })

                request.onsuccess = function(event) {
                    res()
                    console.log('数据更新成功')
                }

                request.onerror = function(event) {
                    rej()
                    console.log('数据更新失败')
                }
            })
        }
        // 删除某个表的数据
        async remove(parm = { dbName, objName, param, response }) {
            await this.open(parm)

            return new Promise((res, rej) => {
                let type = this.getType(parm.param)

                var request = this.db
                    .transaction([parm.objName], 'readwrite')
                    .objectStore(parm.objName)
                    .delete(type ? JSON.stringify(parm.param) : parm.param)

                request.onsuccess = function(event) {
                    res()
                    console.log('数据删除成功')
                }
            })
        }
    }
let db=new DBOpration()//创建数据库实例
//接下来增删改查调取对应的方法就行

总结:localStorage、sessionStorage、Cookie、IndexedDB 不同存储方式的使用场景

  • Cookie:适用于标记用户身份与跟踪用户行为。

  • localStorage:适用于长期保存用户的本地数据,例如 Token。

  • sessionStorage:适合敏感账号的一次性登录场景。

  • IndexedDB:适合存储大量结构化数据,例如富文本编辑器的编辑历史保存等。

这四种本地存储方式均保存在浏览器端,但存在以下主要区别:

  • Cookie 数据在每次 HTTP 请求中都会发送到服务器,而 sessionStorage 和 localStorage 仅在本地保存,不随请求发送。

  • Cookie 数据大小限制为 4KB,而 sessionStorage 和 localStorage 可达 5MB 或更大。

  • sessionStorage 仅在当前会话有效,localStorage 始终有效(除非手动删除),Cookie 则在设置的过期时间之前有效。

  • sessionStorage 不在不同的浏览器窗口中共享,而 localStorage 和 Cookie 在所有同源窗口中共享。

  • IndexedDB 是数据库,可储存大量数据,原生支持存储 JS 对象,所有操作均为异步,相比 localStorage 的同步操作性能更高。

本地存储提供了一种便捷的用户数据持久化方式,但需注意它们均遵循同源策略,不同网站间无法共用存储空间。此外,由于 localStorage 和 sessionStorage 仅支持字符串类型,存储非字符串数据时需进行类型转换。

以上为 JavaScript 中本地存储的 4 种方式及用法与使用场景的汇总,更多关于 JavaScript 本地存储的资料请关注本站其他相关文章!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章