脚本如何设置本地缓存时效

wen 实用脚本 28

本文目录导读:

脚本如何设置本地缓存时效

  1. 使用 localStorage + 时间戳(最常用)
  2. 使用 IndexedDB(适合大量结构化数据)
  3. 使用 sessionStorage(页面会话级缓存)
  4. 使用 Cookie(服务端+客户端双端可用)
  5. 使用 Cache API(Service Worker 专用)
  6. 最佳实践建议
  7. 自动清理过期数据的工具函数

设置本地缓存时效通常需要根据缓存类型采用不同方法,以下是几种常见方案及实现代码:


使用 localStorage + 时间戳(最常用)

// 设置缓存(带过期时间)
function setCache(key, value, ttl) {
  const data = {
    value: value,
    expire: Date.now() + ttl * 1000  // ttl 单位:秒
  }
  localStorage.setItem(key, JSON.stringify(data))
}
// 获取缓存(自动判断是否过期)
function getCache(key) {
  const str = localStorage.getItem(key)
  if (!str) return null
  try {
    const data = JSON.parse(str)
    if (Date.now() > data.expire) {
      localStorage.removeItem(key)  // 过期自动删除
      return null
    }
    return data.value
  } catch {
    return null
  }
}
// 使用示例:缓存10分钟(600秒)
setCache('user_info', {name: '张三'}, 600)
const info = getCache('user_info')

优点:简单、兼容性好
缺点:需要自行清除过期数据


使用 IndexedDB(适合大量结构化数据)

// 封装一个带有过期时间的 IndexedDB 工具
class IndexedDBCache {
  constructor(dbName, storeName) {
    this.dbName = dbName
    this.storeName = storeName
    this.db = null
  }
  async open() {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open(this.dbName, 1)
      request.onupgradeneeded = (e) => {
        const db = e.target.result
        if (!db.objectStoreNames.contains(this.storeName)) {
          const store = db.createObjectStore(this.storeName, { keyPath: 'key' })
          store.createIndex('expire', 'expire', { unique: false })
        }
      }
      request.onsuccess = (e) => {
        this.db = e.target.result
        resolve()
      }
      request.onerror = reject
    })
  }
  async set(key, value, ttl) {
    await this.ensureOpen()
    const transaction = this.db.transaction(this.storeName, 'readwrite')
    const store = transaction.objectStore(this.storeName)
    const data = {
      key,
      value,
      expire: Date.now() + ttl * 1000
    }
    store.put(data)
  }
  async get(key) {
    await this.ensureOpen()
    return new Promise((resolve) => {
      const transaction = this.db.transaction(this.storeName, 'readonly')
      const store = transaction.objectStore(this.storeName)
      const request = store.get(key)
      request.onsuccess = (e) => {
        const data = e.target.result
        if (!data) { resolve(null); return }
        if (Date.now() > data.expire) {
          this.delete(key)
          resolve(null)
        } else {
          resolve(data.value)
        }
      }
      request.onerror = () => resolve(null)
    })
  }
  async delete(key) {
    await this.ensureOpen()
    const transaction = this.db.transaction(this.storeName, 'readwrite')
    const store = transaction.objectStore(this.storeName)
    store.delete(key)
  }
  async ensureOpen() {
    if (!this.db) await this.open()
  }
}
// 使用示例
const dbCache = new IndexedDBCache('myApp', 'cache')
await dbCache.set('api_data', { list: [1,2,3] }, 300)  // 5分钟
const data = await dbCache.get('api_data')

优点:容量大(>5MB)、支持复杂查询、自动清理过期数据
缺点:API 较复杂、需要异步处理


使用 sessionStorage(页面会话级缓存)

// 页面关闭即失效,无需手动设置时效
sessionStorage.setItem('temp_key', '仅当前标签页有效')
// 如果需要自定义过期时间(需配合时间戳,同 localStorage 方案)

适用场景:表单暂存、页面间传递临时数据


使用 Cookie(服务端+客户端双端可用)

// 设置带过期时间的 Cookie(expires 是绝对时间)
document.cookie = `token=abc123; max-age=${3600}; path=/`  // 1小时后过期
// 或使用 expires 字符串
document.cookie = `token=abc123; expires=${new Date(Date.now() + 3600000).toUTCString()}; path=/`

注意:Cookie 有 4KB 大小限制,每次请求都会自动携带


使用 Cache API(Service Worker 专用)

// 在 Service Worker 中设置缓存策略
self.addEventListener('fetch', (event) => {
  event.respondWith(
    caches.match(event.request).then((response) => {
      // 缓存未命中时从网络获取
      return response || fetch(event.request).then((res) => {
        const clone = res.clone()
        caches.open('v1').then((cache) => {
          cache.put(event.request, clone)
        })
        return res
      })
    })
  )
})

最佳实践建议

数据类型 缓存方案 时效设置
简单的字符串/JSON localStorage + 时间戳 按 TTL 秒数
大量数据或文件 IndexedDB 每条记录独立过期
用户登录态 Cookie 服务端设置 max-age
仅当前页面有效 sessionStorage 页面关闭即失效
离线资源 Cache API + Service Worker 使用 cache.addAll 时指定版本

自动清理过期数据的工具函数

// 定期清理所有 localStorage 中的过期项
function clearExpiredKeys() {
  for (let i = 0; i < localStorage.length; i++) {
    const key = localStorage.key(i)
    try {
      const data = JSON.parse(localStorage.getItem(key))
      if (data && data.expire && Date.now() > data.expire) {
        localStorage.removeItem(key)
      }
    } catch { /* 非 JSON 格式跳过 */ }
  }
}
// 页面加载时执行一次
window.addEventListener('load', clearExpiredKeys)
// 或定时执行(例如每10分钟)
setInterval(clearExpiredKeys, 600000)

选择哪种方案取决于你的数据量、持久性要求、是否需要服务端参与等场景,如果只是简单的前端缓存,推荐使用 localStorage + 时间戳 方案,实现简单且足够满足大部分需求。

抱歉,评论功能暂时关闭!