Vue.js调用.NET API渲染图片失败,求最优实现方案
问题:Vue调用.NET图片API无法显示图片
我有一个可返回图片的.NET API Get方法:
[HttpGet("GetImage/{userId}/{imageURL}")] public IActionResult GetImage(string userId, string imageURL) { byte[] b = System.IO.File.ReadAllBytes("../WebServices/ImgLibrary/" + userId + "/" + imageURL); return File(b, "image/png"); }
该方法在Swagger中可正常渲染图片,但在Vue.js项目中调用后无法显示图片。我的Vue调用逻辑如下:
var imgURL = this.baseUrl + "/GetImage/" + user.Id.toString() + "/"; var i; for (i = 0; i < this.imageList.length; i++) { imgURL += this.imageList[i].Name; const imgResponse = await fetch(imgURL,{ method: "GET", }); const thisImg = await imgResponse.blob(); this.imgRawDataList[i] = thisImg imgURL = this.baseUrl + "/GetImage/" + user.Id.toString() + "/"; //reset }
将Blob存入imgRawDataList数组,再通过getRawURL方法转换为base64绑定到img的src:
<div v-for="(ImageD, ImageK) in imageList"> <div v-bind:data-src="ImageD.ImageUrl"> <img v-bind:src="getRawURL(ImageD.ImageUrl, ImageK)" /> </div> </div>
getRawURL(path, i) { if (this.imgRawDataList.length > 0) { if (this.imgRawDataList[i] !== undefined) { return 'data:image/png;base64,' + btoa( new Uint8Array(this.imgRawDataList[i]) .reduce((data, byte) => data + String.fromCharCode(byte), '') ); } else { return ''; } } else { return ''; } },
但btoa方法返回空值,最终img的src仅为"data:image/png;base64,",无法显示图片。想请教:使用Blob是否为最优方案?当前实现是否过于复杂,正确的渲染方式是什么?
解决方案
1. 当前实现的核心问题
你直接把Blob对象传给Uint8Array构造函数是错误的——Uint8Array需要的是ArrayBuffer类型数据,不是Blob。这导致转换后的字符串为空,btoa自然返回空值。
2. 最简最优的渲染方式:直接绑定API地址
完全不需要用fetch下载Blob再转base64,这属于多余操作。直接把API的完整URL赋值给img的src即可,浏览器会自动发起GET请求加载图片:
修改Vue模板
<div v-for="(ImageD, ImageK) in imageList" :key="ImageK"> <img :src="`${baseUrl}/GetImage/${user.Id}/${ImageD.Name}`" /> </div>
这种方式的优势:
- 代码极简,省去所有
fetch和转换逻辑 - 浏览器自动处理缓存,重复加载同一张图片时无需重新请求
- 避免base64转换带来的体积膨胀(base64会比原二进制数据大30%左右)
3. Blob的适用场景
只有在需要对图片数据进行本地处理(比如裁剪、修改像素、上传前预览)时,才需要下载Blob。单纯显示图片的场景下,直接绑定API URL是最优方案。
4. 若必须使用Blob的正确处理方式
如果业务场景确实需要Blob(比如本地操作图片),修正转换逻辑:
方式一:转ArrayBuffer后处理
// 修改fetch后的处理逻辑 const imgResponse = await fetch(imgURL); const arrayBuffer = await imgResponse.arrayBuffer(); // 先转成ArrayBuffer this.imgRawDataList[i] = arrayBuffer; // 存ArrayBuffer而非Blob // 修改getRawURL方法 getRawURL(path, i) { if (!this.imgRawDataList[i]) return ''; return 'data:image/png;base64,' + btoa( new Uint8Array(this.imgRawDataList[i]) .reduce((data, byte) => data + String.fromCharCode(byte), '') ); }
方式二:用FileReader直接转base64
// 修改fetch后的处理逻辑 const imgResponse = await fetch(imgURL); const blob = await imgResponse.blob(); const reader = new FileReader(); reader.onload = (e) => { this.imgRawDataList[i] = e.target.result; // 直接得到base64字符串 }; reader.readAsDataURL(blob);
此时模板中直接绑定imgRawDataList[i]即可,无需额外转换。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

