JavaScript中通过Blob字符串设置HTML图片src失效问题排查
问题描述
尝试将Blob以字符串形式(示例:�PNG IHDR��csRGB���IDATHKݖMJ�@��r=)赋值给img元素的src,但无法正常显示图片。以下是模拟示例:直接操作Blob对象的IMG 1能正常显示,但从Blob读取字符串后赋值的IMG 2无法显示:
var xhr = new XMLHttpRequest(); xhr.open("GET", "https://www.SomeURL.com/SomeImage.png"); xhr.responseType = "blob"; xhr.onload = function(r){ // IMG 1 正常显示 document.getElementById('img1').src = (window.URL || window.webkitURL).createObjectURL(this.response); var fr = new FileReader(); fr.onload = function(e) { // IMG 2 两种写法都无法显示 document.getElementById('img2').src = (window.URL || window.webkitURL).createObjectURL(new Blob([e.target.result], {type:'image/png'})); document.getElementById('img2').src = (window.URL || window.webkitURL).createObjectURL(new Blob([new Uint8Array(e.target.result)], {type:'image/png'})); }; fr.readAsText(this.response); }; xhr.send();
问题原因与解决方法
核心原因
用FileReader.readAsText()读取二进制图片Blob是错误操作——二进制数据转字符串时,会因默认UTF-8编码规则丢失或损坏原始字节信息,再把这个字符串转回Blob时,已经不是原本的图片数据,自然无法被img标签解析。
正确方案
有两种可行的解决方式:
- 方案1:用
readAsArrayBuffer()读取原始二进制数据
读取ArrayBuffer后直接基于它创建Blob,能完整保留原始图片的字节信息。 - 方案2:用
readAsDataURL()直接生成可赋值的Data URL
这种方式会直接返回base64编码的图片字符串,可直接赋值给img的src,无需再创建Blob URL。
方案1代码示例
var xhr = new XMLHttpRequest(); xhr.open("GET", "https://www.SomeURL.com/SomeImage.png"); xhr.responseType = "blob"; xhr.onload = function(r){ // IMG 1 正常显示 document.getElementById('img1').src = (window.URL || window.webkitURL).createObjectURL(this.response); var fr = new FileReader(); fr.onload = function(e) { // 基于ArrayBuffer创建Blob,恢复原始二进制数据 document.getElementById('img2').src = (window.URL || window.webkitURL).createObjectURL(new Blob([e.target.result], {type:'image/png'})); }; // 改用readAsArrayBuffer读取二进制数据 fr.readAsArrayBuffer(this.response); }; xhr.send();
方案2代码示例
var xhr = new XMLHttpRequest(); xhr.open("GET", "https://www.SomeURL.com/SomeImage.png"); xhr.responseType = "blob"; xhr.onload = function(r){ // IMG 1 正常显示 document.getElementById('img1').src = (window.URL || window.webkitURL).createObjectURL(this.response); var fr = new FileReader(); fr.onload = function(e) { // 直接将Data URL赋值给src document.getElementById('img2').src = e.target.result; }; // 改用readAsDataURL生成可直接使用的Data URL fr.readAsDataURL(this.response); }; xhr.send();
内容的提问来源于stack exchange,提问作者Akkad
相关产品推荐
相关产品推荐

