如何在Vue JS中通过axios服务调用动态设置img标签src属性URL并配置兜底图片
实现方案
核心思路
如果后端接口支持直接GET访问、无特殊鉴权/请求方式要求,浏览器可以直接识别接口返回的PNG二进制流并渲染为图片,直接搭配onerror事件即可实现兜底。如果接口需要带自定义header、用POST请求等特殊要求,需先请求二进制流转为Blob对象,再生成临时Object URL赋值给img标签的src属性,同时搭配两层兜底逻辑即可。
1. 接口支持GET无特殊要求的最简方案
<img src="你的图片服务接口地址" alt="展示图片" onerror="this.src='你的兜底备用图片地址'" >
浏览器会自动处理二进制流渲染,加载失败时触发onerror事件自动替换为兜底图。
2. 接口有特殊请求要求的完整实现方案
如果接口需要鉴权、POST传参等,无法直接把地址放到src属性中,需要手动发起请求处理二进制流:
原生JS实现
const targetImg = document.querySelector('#target-img') const fallbackImgUrl = '你的兜底备用图片地址' let tempUrl = null // 页面加载完成后触发请求 window.addEventListener('load', async () => { try { const res = await fetch('你的图片服务接口地址', { method: 'POST', // 按接口实际要求调整 headers: { 'Authorization': 'Bearer 你的鉴权token' // 有鉴权要求则添加 } // 按需添加body等其他请求参数 }) if (!res.ok) throw new Error('图片请求失败') // 二进制流转为Blob对象 const imgBlob = await res.blob() // 生成临时可访问的URL tempUrl = URL.createObjectURL(imgBlob) targetImg.src = tempUrl } catch (err) { // 第一层兜底:请求失败直接用备用图 targetImg.src = fallbackImgUrl } }) // 第二层兜底:防止临时URL转换异常等特殊情况 targetImg.onerror = () => { targetImg.src = fallbackImgUrl } // 页面卸载时清理临时URL,避免内存泄漏 window.addEventListener('unload', () => { if (tempUrl) URL.revokeObjectURL(tempUrl) })
React 实现
import { useState, useEffect } from 'react' const CustomImage = () => { const [imgSrc, setImgSrc] = useState('你的兜底备用图片地址') const fallbackUrl = '你的兜底备用图片地址' useEffect(() => { let tempUrl = null const fetchImage = async () => { try { const res = await fetch('你的图片服务接口地址', { // 按需添加请求配置 }) if (!res.ok) throw new Error() const blob = await res.blob() tempUrl = URL.createObjectURL(blob) setImgSrc(tempUrl) } catch (err) { setImgSrc(fallbackUrl) } } fetchImage() // 组件卸载时清理临时URL return () => { if (tempUrl) URL.revokeObjectURL(tempUrl) } }, []) return <img src={imgSrc} alt="展示图" onError={() => setImgSrc(fallbackUrl)} /> }
Vue 3 实现
<template> <img :src="imgSrc" alt="展示图" @error="handleLoadError" /> </template> <script setup> import { ref, onMounted, onUnmounted } from 'vue' const imgSrc = ref('你的兜底备用图片地址') const fallbackUrl = '你的兜底备用图片地址' let tempUrl = null onMounted(async () => { try { const res = await fetch('你的图片服务接口地址', { // 按需添加请求配置 }) if (!res.ok) throw new Error() const blob = await res.blob() tempUrl = URL.createObjectURL(blob) imgSrc.value = tempUrl } catch (err) { imgSrc.value = fallbackUrl } }) const handleLoadError = () => { imgSrc.value = fallbackUrl } onUnmounted(() => { if (tempUrl) URL.revokeObjectURL(tempUrl) }) </script>
注意事项
URL.createObjectURL生成的临时URL会占用浏览器内存,不再使用时一定要调用URL.revokeObjectURL主动释放,避免内存泄漏- 两层兜底逻辑覆盖了请求失败、资源转换失败、临时URL失效等所有异常场景,不会出现图片占位空白的问题
- 标准PNG格式的二进制流转换为Blob后不需要额外处理格式,浏览器会自动识别MIME类型正常渲染
内容的提问来源于stack exchange,提问作者Rudra
相关产品推荐
相关产品推荐

