将base64数组存入JSON发送POST请求时数组为空如何解决
问题根因
你遇到的是异步执行时序问题,并非base64存入JSON的方法有误:FileReader的onload回调属于异步任务,你在遍历触发文件读取操作后立刻发送请求,此时所有onload回调都还未执行,filesBody实际是空数组。
控制台能看到完整内容是因为控制台打印的是数组的引用,等后续异步回调执行往数组中插入数据后,控制台展示的内容也同步更新,和你发送请求时的数组状态不属于同一个时间节点。
解决方案
用Promise封装所有文件转base64的异步操作,等所有转换任务全部完成后,再组装请求体调用接口。
首先封装单个文件转base64的公共方法:
// 单个File对象转base64的Promise封装 const fileToBase64 = (file) => { return new Promise((resolve, reject) => { const reader = new FileReader(); reader.readAsDataURL(file); reader.onload = () => resolve(reader.result); reader.onerror = (err) => reject(err); }); }
再调整业务逻辑,等所有文件转换完成后再发请求:
// 批量转换所有文件,全部完成后执行接口请求 Promise.all(this.files.map(item => fileToBase64(item))) .then(filesBody => { const body = { files: filesBody }; // 此处再调用接口发送数据 this.billingService.sendBillingRevaluation(body).subscribe(); }) .catch(err => { console.error('图片转码失败', err); })
额外注意事项
- 如果你的开发环境支持async/await语法,可以用同步风格实现相同逻辑,代码可读性更高
- base64格式会比原文件体积大33%左右,如果需要传输大体积图片,优先使用
FormData格式上传二进制文件,传输性能更好 - 调试时可以通过
console.log(JSON.stringify(body))打印请求体序列化后的真实内容,避免控制台引用对象动态更新带来的判断误差
内容的提问来源于stack exchange,提问作者Leticia Fatima
相关产品推荐
相关产品推荐

