前言
随着Web应用的发展,存储用户数据的需求变得越来越重要。现代浏览器提供了多种客户端存储方案,包括 localStorage
, sessionStorage
, Cookies
, 已经被废弃的 Web SQL
,以及功能强大的 IndexedDB
。本文将详细介绍这些技术的基本概念和使用方法。
正文
1. localStorage
:简单的键值对存储
localStorage
是一种允许网站在用户的浏览器中存储数据的技术,它提供了持久化的存储能力,除非用户主动清除
浏览器缓存,否则数据不会丢失。localStorage
以字符串的形式存储数据,每个域名下大约有5MB的存储空间。
示例代码
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="save">保存</button>
<button id="get">读取</button>
<button id="del">删除</button>
<button id="clear">清空</button>
<script>
const user = {
name: '剑哥',
age: 18
}
document.getElementById('save').addEventListener('click', () => {
// 将对象转换为JSON字符串并保存
localStorage.setItem('userInfo', JSON.stringify(user))
})
document.getElementById('get').addEventListener('click', () => {
// 从localStorage中获取数据并解析为对象
console.log(JSON.parse(localStorage.getItem('userInfo')));
})
document.getElementById('del').addEventListener('click', () => {
// 删除指定的键值对
localStorage.removeItem('userInfo')
})
document.getElementById('clear').addEventListener('click', () => {
// 清空所有数据
localStorage.clear()
})
</script>
</body>
</html>
基本操作
- 保存数据 :
localStorage.setItem('key', 'value')
- 读取数据 :
localStorage.getItem('key')
- 删除数据 :
localStorage.removeItem('key')
- 清空所有数据 :
localStorage.clear()
注意
localStorage
的数据是基于域名(即协议 + 域名 + 端口)进行隔离的。这意味着以下几点:
- 相同域名 :如果两个页面属于同一个域名,它们可以访问相同的
localStorage
数据。 - 不同子域名 :如果两个页面属于同一个顶级域名的不同子域名(例如
a.example.com
和b.example.com
),它们不能直接访问对方的localStorage
数据。不过,可以通过设置文档的document.domain
属性来实现跨子域共享localStorage
。 - 不同协议 :如果两个页面的协议不同(例如
http://example.com
和https://example.com
),它们被视为不同的域名,不能共享localStorage
数据。 - 不同端口 :如果两个页面的端口不同(例如
http://example.com:8080
和http://example.com:8081
),它们也被视为不同的域名,不能共享localStorage
数据。
2. sessionStorage
:会话级别的存储
sessionStorage
与 localStorage
类似,也是用于存储字符串形式的数据。不同之处在于,sessionStorage
存储的数据仅在当前会话期间可用,当浏览器窗口关闭时,数据会被清除。
示例代码
依旧是这个例子:
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button id="save">保存</button>
<button id="get">读取</button>
<button id="del">删除</button>
<button id="clear">清空</button>
<script>
const user = {
name: '剑哥',
age: 18
}
document.getElementById('save').addEventListener('click', () => {
sessionStorage.setItem('key', JSON.stringify(user))
})
document.getElementById('get').addEventListener('click', () => {
console.log(sessionStorage.getItem('key'));
})
document.getElementById('del').addEventListener('click', () => {
sessionStorage.removeItem('key')
})
document.getElementById('clear').addEventListener('click', () => {
sessionStorage.clear()
})
</script>
</body>
</html>
跟localStorage用法类似
3.Cookies
Cookies
是不受前端掌控的,由后端控制,它是一种在用户浏览器上存储信息的方法,主要用于跟踪用户活动和保持用户登录状态等目的。与 localStorage
和 sessionStorage
不同,它是由服务器发送给用户的,通常包含在 HTTP 响应头中。用户浏览器会将这些 Cookies 保存起来,并在后续请求同一服务器时自动将其包含在 HTTP 请求头中返回给服务器。
特点
- 自动发送:浏览器会自动将相关 Cookies 发送到对应的服务器,无需额外编程。
- 大小限制:每个域名下的 Cookies 总量有限制,通常是 4KB 左右。
- 安全性 :可以通过设置
HttpOnly
标志来防止 JavaScript 访问 Cookies,从而减少 XSS 攻击的风险。 - 过期时间 :可以通过设置
Expires
或Max-Age
属性来控制 Cookie 的有效期。 - 路径和域 :可以设置
Path
和Domain
属性来限制 Cookie 的适用范围。
4. IndexedDB
:高级的本地数据库
IndexedDB
是是浏览器本地的数据库,支持事务处理、异步操作等特性,支持使用js 编写逻辑来创建,适合存储大量结构化数据,并提供搜索功能。与 localStorage
和 sessionStorage
相比,IndexedDB
的存储量更大,没有明确的大小限制,也是永久存储的。
示例代码
HTML 部分
xml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IndexedDB Example</title>
<style>
/* 一些简单的样式 */
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid black;
padding: 8px;
text-align: left;
}
th {
background-color: #f2f2f2;
}
</style>
</head>
<body>
<!-- 按钮用于触发不同的数据库操作 -->
<button onclick="openDB()">连接、新建数据库</button>
<button onclick="insertOneDB()">插入一条数据</button>
<button onclick="insertMultiDB()">插入多条数据</button>
<button onclick="queryDB()">查询数据</button>
<button onclick="updateDB()">更新数据</button>
<button onclick="deleteDB()">删除数据</button>
<script>
// JavaScript 代码部分
</script>
</body>
</html>
JavaScript 部分
定义常量和变量
ini
const dbName = 'users'; // 数据库名称
const dbVersion = 1.0; // 数据库版本
let db = null; // 用于存储数据库实例
连接、新建数据库
javascript
function openDB() {
const request = indexedDB.open(dbName, dbVersion); // 打开或创建数据库
request.onerror = function(event) {
console.error('无法打开数据库', event.target.error); // 错误处理
};
request.onupgradeneeded = function(event) {
db = event.target.result; // 获取数据库实例
// 如果不存在名为 'sex' 的对象存储,则创建它
if (!db.objectStoreNames.contains('sex')) {
const objectStore = db.createObjectStore('sex', { keyPath: 'id' });
objectStore.createIndex('title', 'title', { unique: true }); // 创建唯一索引
}
};
request.onsuccess = function(event) {
db = event.target.result;
console.log(`数据库${db.name}已经开启`); // 成功打开数据库
};
}
基本操作
indexedDB.open(dbName, dbVersion)
: 打开或创建数据库。db.createObjectStore(storeName, options)
: 创建对象存储。objectStore.createIndex(indexName, keyPath, options)
: 创建索引。
插入一条数据
javascript
function insertOneDB() {
const transaction = db.transaction(['sex'], 'readwrite'); // 开启事务
const objectStore = transaction.objectStore('sex'); // 获取对象存储
const data = { id: 1, title: '男生', author: '张三', createAt: Date.now() }; // 要插入的数据
const request = objectStore.add(data); // 插入数据
request.onerror = function(event) {
console.error('数据写入失败', event.target.error); // 错误处理
};
request.onsuccess = function() {
console.log('数据写入成功'); // 成功插入数据
};
}
基本操作
db.transaction([storeName], mode)
: 开启事务。transaction.objectStore(storeName)
: 获取对象存储。objectStore.add(data)
: 插入数据。
插入多条数据
javascript
function insertMultiDB() {
const data = [
{ id: 2, title: '男生1', author: '李四', createAt: Date.now() },
{ id: 3, title: '男生2', author: '王二', createAt: Date.now() },
{ id: 4, title: '女生', author: '柳如烟', createAt: Date.now() }
];
const transaction = db.transaction(['sex'], 'readwrite'); // 开启事务
const objectStore = transaction.objectStore('sex'); // 获取对象存储
data.forEach((item) => {
const request = objectStore.add(item); // 插入每条数据
request.onsuccess = function() {
console.log('数据已添加'); // 成功插入数据
}
});
transaction.oncomplete = function() {
console.log('所有数据写入完成'); // 所有数据插入完成
};
}
基本操作
db.transaction([storeName], mode)
: 开启事务。transaction.objectStore(storeName)
: 获取对象存储。objectStore.add(data)
: 插入数据。transaction.oncomplete
: 事务完成时的回调。
查询数据
ini
function queryDB() {
const transaction = db.transaction(['sex'], 'readonly'); // 开启只读事务
const objectStore = transaction.objectStore('sex'); // 获取对象存储
const index = objectStore.index('title'); // 获取索引
const range = IDBKeyRange.only('女生'); // 创建范围,只查询标题为 '女生' 的数据
const request = index.openCursor(range); // 打开游标
request.onsuccess = function(event) {
const cursor = event.target.result;
if (cursor) {
console.log(cursor.value); // 输出匹配的数据
cursor.continue(); // 继续遍历
}
};
const req = objectStore.get(1); // 通过 ID 查询数据
req.onerror = function() {
console.log('查找失败'); // 错误处理
};
req.onsuccess = function() {
console.log(req.result); // 输出查询结果
};
}
基本操作
db.transaction([storeName], mode)
: 开启事务。transaction.objectStore(storeName)
: 获取对象存储。objectStore.index(indexName)
: 获取索引。IDBKeyRange.only(key)
: 创建一个范围,只包含指定的键。index.openCursor(range)
: 打开游标。objectStore.get(key)
: 通过键获取数据。
更新数据
javascript
function updateDB() {
const transaction = db.transaction(['sex'], 'readwrite'); // 开启事务
const objectStore = transaction.objectStore('sex'); // 获取对象存储
const data = { id: 1, title: '男生更新', author: '张三', createAt: Date.now() }; // 要更新的数据
const request = objectStore.put(data); // 更新数据
request.onerror = function(event) {
console.error('数据更新失败', event.target.error); // 错误处理
};
request.onsuccess = function() {
console.log('数据更新成功'); // 成功更新数据
};
}
基本操作
db.transaction([storeName], mode)
: 开启事务。transaction.objectStore(storeName)
: 获取对象存储。objectStore.put(data)
: 更新数据。
删除数据
ini
function deleteDB() {
const transaction = db.transaction(['sex'], 'readwrite'); // 开启事务
const objectStore = transaction.objectStore('sex'); // 获取对象存储
const idToDelete = 1; // 要删除的 ID
const request = objectStore.delete(idToDelete); // 删除数据
request.onerror = function(event) {
console.error('数据删除失败', event.target.error); // 错误处理
};
request.onsuccess = function() {
console.log('数据删除成功'); // 成功删除数据
};
}
基本操作
db.transaction([storeName], mode)
: 开启事务。transaction.objectStore(storeName)
: 获取对象存储。objectStore.delete(key)
: 删除数据。
效果:
总结
通过上述示例,我们介绍了 localStorage, sessionStorage, Cookies和 IndexedDB 的,localStorage
和 sessionStorage
适用于简单的键值对存储,而IndexedDB
则提供了更强大的功能,适合存储大量结构化数据。希望本文能帮助你更好地理解和使用这些浏览器本地存储技术,感谢你的阅读!