未设置responseType为blob时,XHR加载得到的图片字符串能否正常渲染
问题根因
XMLHttpRequest默认responseType为text,会将响应的二进制图片数据按UTF-8规则解析为字符串。图片二进制字节不符合UTF-8编码规范,解析过程中会被篡改、替换,因此直接将得到的字符串转换为Blob无法还原出有效图片。
解决方案
最优方案(推荐)
直接在请求初始化阶段指定responseType为blob,无需额外转换即可拿到可直接使用的图片二进制对象:
const xhr = new XMLHttpRequest() xhr.open('GET', '/binary/your-image-path') // 核心配置,直接接收二进制Blob响应 xhr.responseType = 'blob' xhr.onload = function() { if (xhr.status === 200) { const imgBlob = xhr.response // 生成可访问的图片地址 const renderUrl = URL.createObjectURL(imgBlob) // 赋值给img标签的src属性即可正常渲染 // document.querySelector('img').src = renderUrl } } xhr.send()
你的Node后端返回逻辑是正常的,res.sendFile已经正确返回图片二进制流,不需要做额外修改。
兼容方案(无法修改responseType时使用)
如果受业务限制不能修改responseType配置,可以通过覆盖MIME类型强制浏览器保留原始二进制字节,再手动转换为Blob:
const xhr = new XMLHttpRequest() // 强制浏览器按单字节编码解析响应,不篡改原始字节 xhr.overrideMimeType('text/plain; charset=x-user-defined') xhr.open('GET', '/binary/your-image-path') xhr.onload = function() { if (xhr.status === 200) { const rawStr = xhr.responseText const byteArr = new Uint8Array(rawStr.length) // 提取每个字符的低8位,还原为原始二进制字节 for (let i = 0; i < rawStr.length; i++) { byteArr[i] = rawStr.charCodeAt(i) & 0xff } const imgBlob = new Blob([byteArr], { type: 'image/jpeg' }) const renderUrl = URL.createObjectURL(imgBlob) // 赋值给img标签的src属性即可正常渲染 } } xhr.send()
内容的提问来源于stack exchange,提问作者Jeanluca Scaljeri
相关产品推荐
相关产品推荐

