Angular 6项目中Safari无法删除Cache API缓存文件问题求助
Safari中Cache API删除缓存失败并触发Quota Exceeded的解决方案
我之前也遇到过Safari对Cache API的兼容性问题,咱们来一步步解决你碰到的这个问题:
问题根源分析
Safari的Cache API实现和Chrome存在不少差异,其中最关键的两点是:
- 删除整个缓存时,Safari不会立即释放对应的存储空间,系统回收资源的延迟会导致再次保存时触发配额超限。
- 对缓存条目的引用管理更严格,直接删除缓存实例可能无法彻底清理关联的资源。
针对性解决方案
1. 删除特定缓存条目而非整个缓存
你的removeFile()方法是直接删除整个缓存实例,这在Safari里容易出现资源残留。改成先打开缓存,删除目标URL对应的条目,再按需删除空缓存:
removeFile() { this.resetValues(); caches.open(this.id).then((cache) => { // 先删除指定URL的缓存条目 return cache.delete(this.url).then((isEntryDeleted) => { console.log("Specific file entry removed:", isEntryDeleted); // 如果缓存为空,再删除整个缓存实例 return cache.keys().then((remainingKeys) => { if (remainingKeys.length === 0) { return caches.delete(this.id).then((isCacheDeleted) => { console.log("Empty cache instance deleted:", isCacheDeleted); }); } }); }).then(() => { this.status = 'File removed'; }); }).catch((error: Error) => { this.errorMessage = error.message; console.error('Error removing file from cache :(', error); }); }
2. 克隆Fetch响应再存入缓存
Safari对Fetch响应的一次性使用限制更严格,直接存入缓存可能导致响应资源未被正确释放。修改saveFile()方法,克隆响应后再存入:
saveFile() { this.resetValues(); caches.open(this.id).then((cache) => { // 先检查缓存是否已存在该文件,避免重复占用空间 return cache.match(this.url).then((existingEntry) => { if (existingEntry) { this.status = 'File already exists in cache'; return Promise.resolve(); } return fetch(this.url).then((response) => { console.log("fetch complete", response); // 克隆响应后存入缓存 return cache.put(this.url, response.clone()).then((data) => { console.log("cache complete", data) this.status = 'File saved'; }); }); }); }).catch((error: Error) => { this.errorMessage = error.message; console.error('Error caching file!', error); }); }
3. 额外优化:主动清理过期/无用缓存
如果你的应用会缓存多个文件,建议定期清理无用缓存,避免Safari的配额被占满:
async cleanupOldCaches() { const cacheNames = await caches.keys(); for (const name of cacheNames) { // 根据你的缓存命名规则,过滤需要保留的缓存 if (!name.startsWith(this.id)) { await caches.delete(name); console.log("Cleaned up old cache:", name); } } }
验证步骤
按照这个修改后,再按你的重现步骤测试:
- 打开Safari,点击"Save file"
- 点击"Remove file",此时会先删除条目,再清理空缓存
- 再次点击"Save file",应该不会再触发Quota Exceeded错误
内容的提问来源于stack exchange,提问作者Daniel Muñoz
相关产品推荐
相关产品推荐

