JavaScript如何从服务端返回的图片内容重建图片生成有效Blob对象
服务端返回图片内容转合法Blob对象方案
问题复现
通过FormData向服务端上传图片后,服务端直接返回图片二进制内容,先后尝试将返回内容封装为Blob、File对象,使用FileReader解析均未生效,异常结果如下:
最后尝试的实现逻辑为,先执行:const img = new Image(response.data);
再调用如下转换函数:
const ImageDataToBlob = function(imageData){ let w = imageData.width; let h = imageData.height; let canvas = document.createElement("canvas"); canvas.width = w; canvas.height = h; let ctx = canvas.getContext("2d"); ctx.putImageData(imageData, 0, 0, w, h); // synchronous return new Promise((resolve, reject) => { canvas.toBlob(resolve); // implied image/png format }) }
执行ctx.putImageData(imageData, 0, 0, w, h);语句时代码抛出异常,无法得到可用的Blob对象。
错误原因
new Image()的入参要求是图片资源的URL地址,直接传入二进制响应数据无法生成可用的图片实例- 上述转换函数的入参要求是
ImageData类型(canvas像素数据对象),传入未正确初始化的Image实例时类型完全不匹配,必然触发putImageData调用异常 - 若使用axios等常见请求库,默认响应类型为
json,二进制返回值会被自动转码损坏,直接封装得到的Blob会是乱码文件,和截图中异常表现一致
正确实现步骤
- 发起请求时必须指定响应类型为二进制格式,避免数据被转码损坏,以axios为例:
// 上传请求增加responseType配置,这是最核心的步骤 const response = await axios.post('/your/upload/interface', formData, { responseType: 'blob' })
- 此时拿到的
response.data本身就是合法的图片Blob对象,可直接使用。如果需要转为File对象用于后续上传,直接封装即可:
// 直接获取可用Blob const validImageBlob = response.data // 转File对象示例 const imageFile = new File([validImageBlob], 'target-image.png', { type: 'image/png' })
- 如果需要将图片用于渲染、canvas二次处理,不要直接把二进制数据传入Image,要生成临时Blob URL使用:
const img = new Image() // 生成临时资源地址 img.src = URL.createObjectURL(validImageBlob) img.onload = () => { // 图片加载完成后再执行canvas操作 const canvas = document.createElement('canvas') canvas.width = img.width canvas.height = img.height const ctx = canvas.getContext('2d') // 注意绘制图片用drawImage,不是putImageData ctx.drawImage(img, 0, 0) // 释放临时URL,避免内存泄漏 URL.revokeObjectURL(img.src) // 后续需要导出Blob可直接调用canvas.toBlob }
注意:如果请求阶段没有配置正确的响应类型,拿到的是被转码损坏的字符串数据,后续任何封装、转换操作都无法得到正常的图片文件,必须先修正请求配置。
内容的提问来源于stack exchange,提问作者assembler
相关产品推荐
相关产品推荐

