如何使用Axios替代Fetch实现结合Cache API的图片缓存?
问题解决:Axios下载文件并适配Cache API存储
核心原因
Axios返回的响应对象是自身封装的实例,并非浏览器原生的Response类型,而Cache API的cache.put()方法仅接受原生Response对象作为参数,这就是报错的根本原因。之前直接用Axios响应实例创建Response的方式无效,是因为没有正确提取响应中的二进制数据。
可行解决方案
通过Axios获取Blob格式的响应数据,再用该数据构建符合要求的原生Response,同时保留进度监听和中断下载功能:
完整代码示例
// 初始化中断控制器(Axios支持CancelToken或AbortController,二选一) const cancelSource = axios.CancelToken.source(); // 或使用AbortController(Axios 0.22.0+支持) // const abortController = new AbortController(); // 发起Axios请求 axios.get(url, { responseType: 'blob', // 关键:指定响应类型为Blob onDownloadProgress: (progressEvent) => { // 计算并展示下载进度 const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total); console.log(`下载进度:${progress}%`); }, cancelToken: cancelSource.token, // 绑定中断令牌 // 若用AbortController则替换为:signal: abortController.signal }).then(async (axiosRes) => { if (axiosRes.status !== 200) { throw new TypeError("Bad response status"); } // 用Axios返回的Blob构建原生Response const nativeResponse = new Response(axiosRes.data, { status: axiosRes.status, statusText: axiosRes.statusText, headers: new Headers(axiosRes.headers) }); // 存入Cache API await cache.put(url, nativeResponse); }).catch((err) => { if (axios.isCancel(err)) { console.log('下载已中断:', err.message); } else { console.error('下载失败:', err); } }); // 触发中断下载的示例(比如用户点击按钮时调用) // cancelSource.cancel('用户主动中断下载'); // 或用AbortController:abortController.abort();
关键说明
- 指定
responseType: 'blob':确保Axios返回的data是浏览器原生Blob对象,这是构建有效Response的核心。 - 手动构建原生
Response:将Blob数据作为响应体,同时复制Axios响应中的状态码、状态文本和请求头,保证Cache API存储的响应完整性。 - 中断下载实现:通过Axios的
CancelToken或AbortController实现下载中断,满足需求。
关于stream类型的说明
浏览器环境下Axios的responseType: 'stream'支持有限(更多适用于Node.js环境),因此优先使用blob类型适配前端场景。
内容的提问来源于stack exchange,提问作者Lauren
相关产品推荐
相关产品推荐

