实现图片本地缓存,减少url重复请求
·
缓存实现代码
/**
* 全能型获取图片缓存 (兼容单个链接与链接数组 + 秒开优化)
*/
export function getImageStorage(url) {
return new Promise((resolve) => {
// 1. 如果是数组,通过 map 循环调用自身,并用 Promise.all 等待所有结果
if (Array.isArray(url)) {
Promise.all(url.map(item => getImageStorage(item)))
.then(results => resolve(results))
.catch(() => resolve(url)); // 异常兜底,返回原数组
return;
}
// 2. 单个链接处理逻辑
if (!url) {
resolve('');
return;
}
// 智能处理 baseUrl 拼接(防止完整的 http/https 链接被重复拼接)
// 注意:请确保你的工具文件里已经定义了 baseUrl,如果 url 已经是完整链接则不拼接
const fullUrl = (url.startsWith('http://') || url.startsWith('https://'))
? url
: (typeof baseUrl !== 'undefined' ? baseUrl + url : url);
// 提取文件名作为缓存 key(兼容带参数的 OSS 链接)
const pathWithoutQuery = fullUrl.split('?')[0];
const fullFileName = pathWithoutQuery.substring(pathWithoutQuery.lastIndexOf('/') + 1);
const fileNameWithoutExt = fullFileName.substring(0, fullFileName.lastIndexOf('.')) || fullFileName;
const storageKey = "IMG_CACHE_" + fileNameWithoutExt; // 本地文件路径缓存 key
const urlCacheKey = "URL_CACHE_" + fileNameWithoutExt; // 网络链接兜底缓存 key
// --- 核心秒开逻辑:优先读取本地缓存的下载路径 ---
const localUrl = uni.getStorageSync(storageKey);
if (localUrl) {
uni.setStorageSync(urlCacheKey, fullUrl); // 顺便更新一下网络链接缓存
resolve(localUrl);
return;
}
// --- 核心秒开逻辑:如果没有本地文件,看看有没有缓存的网络链接 ---
const cachedUrl = uni.getStorageSync(urlCacheKey);
if (cachedUrl) {
resolve(cachedUrl); // 立刻返回缓存的链接,让页面先渲染出来(实现秒开)
}
// 3. 执行下载和持久化缓存逻辑
// #ifndef H5
uni.downloadFile({
url: fullUrl,
success: (res) => {
if (res.statusCode === 200) {
const saveSuccess = (savedFilePath) => {
uni.setStorageSync(storageKey, savedFilePath);
uni.setStorageSync(urlCacheKey, fullUrl);
resolve(savedFilePath);
};
const saveFail = () => resolve(fullUrl); // 失败兜底返回原链接
// #ifndef MP-WEIXIN || MP-KUAISHOU
uni.saveFile({ tempFilePath: res.tempFilePath, success: (r) => saveSuccess(r.savedFilePath), fail: saveFail });
// #endif
// #ifdef MP-WEIXIN
wx.getFileSystemManager().saveFile({ tempFilePath: res.tempFilePath, success: (r) => saveSuccess(r.savedFilePath), fail: saveFail });
// #endif
// #ifdef MP-KUAISHOU
ks.saveFile({ tempFilePath: res.tempFilePath, success: (r) => saveSuccess(r.savedFilePath), fail: saveFail });
// #endif
} else {
resolve(fullUrl);
}
},
fail: () => resolve(fullUrl),
})
// #endif
// #ifdef H5
// H5端 fetchBlobDataAsBase64 逻辑(需确保你文件里有这个辅助函数)
fetchBlobDataAsBase64(fullUrl)
.then(base64Data => {
const [header, data] = base64Data.split(',');
const mimeType = header.match(/:(.*?);/)[1];
const base64 = `data:${mimeType};base64,${data}`;
uni.setStorageSync(storageKey, base64);
uni.setStorageSync(urlCacheKey, fullUrl);
resolve(base64);
})
.catch(() => resolve(fullUrl))
// #endif
});
}
// H5端辅助函数
function fetchBlobDataAsBase64(blobUrl) {
return new Promise((resolve, reject) => {
fetch(blobUrl)
.then(response => response.blob())
.then(blob => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.onerror = () => reject(new Error('无法读取文件'));
reader.readAsDataURL(blob);
})
.catch(error => reject(error));
});
}
使用方法
引入方法--import {getImageStorage} from '../../../util/chatImage.js',根据实际项目写入正确路劲。
在首次获取图片资源的时候调用方法,实现数据缓存this.rulesImageUrl = await getImageStorage(res.data.rulesImageUrl);
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)