feat(图片缓存工具): 局域网链接,当浏览器没有 window.caches 时,不再报错,而是降级成普通 fetch + blob + object URL,直接使用网络加载

This commit is contained in:
hzj 2026-04-24 17:16:09 +08:00
parent d08860c544
commit 61700dd24b

View File

@ -49,6 +49,11 @@ class ImageCacheManager {
return currentMajor > cachedMajor
}
getCacheStorage() {
if (typeof window === 'undefined') return null
return window.caches || null
}
// 返回对应的缓存
async getCacheForUrl(url) {
// 规范化 URL
@ -67,8 +72,12 @@ class ImageCacheManager {
cacheName = this.imageCacheName
}
if (!this.getCacheStorage()) {
return { cache: null, cacheName }
}
try {
const cache = await caches.open(cacheName)
const cache = await this.getCacheStorage().open(cacheName)
return { cache, cacheName } // 返回包含缓存和名称的对象
} catch (error) {
console.error(`打开缓存失败: ${cacheName}`, error)
@ -233,17 +242,18 @@ class ImageCacheManager {
// 清除旧的OSS图片缓存
async clearOldImageCaches() {
if (!('caches' in window)) return
const cacheStorage = this.getCacheStorage()
if (!cacheStorage) return
try {
const cacheNames = await caches.keys()
const cacheNames = await cacheStorage.keys()
const oldImageCaches = cacheNames.filter(
(name) =>
name.startsWith('likei-images-v') && !name.includes(`v${this.currentImageVersion}`), // 排除当前版本的缓存
)
console.log('正在清除旧的OSS图片缓存:', oldImageCaches)
await Promise.all(oldImageCaches.map((name) => caches.delete(name)))
await Promise.all(oldImageCaches.map((name) => cacheStorage.delete(name)))
this.currentImageCacheSize = 0 // 重置计数器
} catch (error) {
console.warn('清理旧的OSS图片缓存失败:', error)
@ -252,17 +262,18 @@ class ImageCacheManager {
// 清除旧的本地assets缓存
async clearOldAssetCaches() {
if (!('caches' in window)) return
const cacheStorage = this.getCacheStorage()
if (!cacheStorage) return
try {
const cacheNames = await caches.keys()
const cacheNames = await cacheStorage.keys()
const oldAssetCaches = cacheNames.filter(
(name) =>
name.startsWith('likei-assets-v') && !name.includes(`v${this.currentImageVersion}`), // 排除当前版本的缓存
)
console.log('正在清除旧的本地assets缓存:', oldAssetCaches)
await Promise.all(oldAssetCaches.map((name) => caches.delete(name)))
await Promise.all(oldAssetCaches.map((name) => cacheStorage.delete(name)))
this.currentAssetCacheSize = 0 // 重置计数器
} catch (error) {
console.warn('清理旧的本地assets缓存失败:', error)
@ -271,16 +282,17 @@ class ImageCacheManager {
// 清除所有图片缓存OSS图片、本地assets图片
async clearAllCaches() {
if (!('caches' in window)) return
const cacheStorage = this.getCacheStorage()
if (!cacheStorage) return
try {
const cacheNames = await caches.keys()
const cacheNames = await cacheStorage.keys()
const allCaches = cacheNames.filter(
(name) => name.startsWith('likei-images-v') || name.startsWith('likei-assets-v'),
)
console.log('正在清除所有图片缓存:', allCaches)
await Promise.all(allCaches.map((name) => caches.delete(name)))
await Promise.all(allCaches.map((name) => cacheStorage.delete(name)))
// 重置计数器
this.currentImageCacheSize = 0
this.currentAssetCacheSize = 0
@ -328,7 +340,7 @@ class ImageCacheManager {
// 从缓存获取图片
async getCachedImage(url) {
if (!('caches' in window)) return null
if (!this.getCacheStorage()) return null
try {
// 规范化 URL
@ -337,6 +349,7 @@ class ImageCacheManager {
// 只从缓存获取本地资源
if (this.isBuildAsset(normalizedUrl)) {
const { cache, cacheName } = await this.getCacheForUrl(normalizedUrl) // 选中对应缓存
if (!cache) return null
// 尝试多种匹配方式
// 带配置的 Request 对象匹配:严格匹配具有特定 CORS 配置和凭证策略的缓存响应,确保请求模式一致
@ -460,6 +473,10 @@ class ImageCacheManager {
if (this.isBuildAsset(src)) {
const { cache, cacheName } = await this.getCacheForUrl(src)
if (!cache) {
const blob = await response.blob()
return URL.createObjectURL(blob)
}
const clonedResponse = response.clone() // 克隆响应用于缓存
await cache.put(src, clonedResponse) // 写入缓存