sessionStorage是Web Storage API的重要组成部分,为每个源(origin)维护独立的会话级存储空间。其数据存储遵循以下核心特性:
特性 | sessionStorage | localStorage |
---|---|---|
生命周期 | 会话级(标签页关闭清除) | 永久存储(需手动清除) |
作用域 | 单标签页内有效 | 同源所有标签页共享 |
存储事件传播 | 仅当前标签页触发 | 所有同源标签页同步触发 |
典型应用场景 | 临时会话数据存储 | 长期偏好设置存储 |
// 存储数据(注意:键值都必须是字符串)
sessionStorage.setItem('userSession', JSON.stringify({
token: 'abc123',
lastActivity: Date.now()
}));
// 读取数据
const sessionData = JSON.parse(
sessionStorage.getItem('userSession') || '{}'
);
// 删除指定键
sessionStorage.removeItem('tempSettings');
// 清空所有存储
sessionStorage.clear();
// 获取键名列表
const keys = Array.from({ length: sessionStorage.length }, (_, i) =>
sessionStorage.key(i)
);
// 监听同源页面的storage事件
window.addEventListener('storage', (event) => {
console.log('存储变更:', {
key: event.key,
oldValue: event.oldValue,
newValue: event.newValue,
url: event.url,
storageArea: event.storageArea
});
});
事件触发条件:
window.open
或
创建的子页面// 实时保存表单数据
const form = document.getElementById('multiStepForm');
form.addEventListener('input', debounce(() => {
const formData = new FormData(form);
sessionStorage.setItem('draftForm', JSON.stringify(Object.fromEntries(formData)));
}, 500));
// 页面加载时恢复数据
window.addEventListener('load', () => {
const savedData = sessionStorage.getItem('draftForm');
if (savedData) {
populateForm(JSON.parse(savedData));
}
});
<script setup>
import { watch } from 'vue';
import { useRoute } from 'vue-router';
const route = useRoute();
// 保存滚动位置
const saveScrollPos = () => {
sessionStorage.setItem(
`scrollPos_${route.path}`,
window.scrollY
);
};
// 恢复滚动位置
const restoreScrollPos = () => {
const savedPos = sessionStorage.getItem(`scrollPos_${route.path}`);
window.scrollTo(0, Number(savedPos) || 0);
};
watch(route, (newVal, oldVal) => {
saveScrollPos();
restoreScrollPos();
});
script>
// 安全存储认证令牌(示例)
const AuthService = {
setToken(token) {
sessionStorage.setItem('authToken', token);
setTimeout(() => {
sessionStorage.removeItem('authToken'); // 15分钟后自动清除
}, 900000);
},
getToken() {
return sessionStorage.getItem('authToken');
}
};
import CryptoJS from 'crypto-js';
const SECRET_KEY = 'your-encryption-key';
function secureSetItem(key, value) {
const ciphertext = CryptoJS.AES.encrypt(
JSON.stringify(value),
SECRET_KEY
).toString();
sessionStorage.setItem(key, ciphertext);
}
const getSafeItem = (key) => {
try {
return JSON.parse(sessionStorage.getItem(key)) || {};
} catch (e) {
sessionStorage.removeItem(key);
return {};
}
};
// 批量存储示例
const batchStore = (items) => {
const transaction = {};
items.forEach(([key, value]) => {
transaction[key] = value;
});
sessionStorage.setItem('batchData', JSON.stringify(transaction));
};
import LZString from 'lz-string';
sessionStorage.setItem(
'bigData',
LZString.compress(JSON.stringify(largeDataSet))
);
function safeStorageOperation(fn) {
try {
return fn();
} catch (e) {
if (e.name === 'QuotaExceededError') {
console.error('存储空间不足');
sessionStorage.clear();
}
return null;
}
}
// 使用示例
safeStorageOperation(() => {
sessionStorage.setItem('bigData', largeData);
});
答案:默认情况下,每个标签页拥有独立的sessionStorage空间。但通过window.open
打开的页面会继承父页面的sessionStorage(仅限同源)
答案:现代浏览器具有崩溃恢复机制,可能保留sessionStorage数据,但不应依赖此特性设计关键业务逻辑
解决方案:结合localStorage和storage事件
// 页面A
localStorage.setItem('sharedMsg', 'update');
// 页面B
window.addEventListener('storage', (e) => {
if (e.key === 'sharedMsg') {
handleMessage(e.newValue);
}
});
支持情况:
sessionStorage作为临时会话存储的利器,在以下场景中表现卓越:
使用原则:
对于需要持久化存储的场景,建议结合IndexedDB或localStorage实现分层存储架构。正确使用sessionStorage能显著提升用户体验,同时保障数据安全性。