如何在结合redux-form使用的react-dropzone中获取文件base64编码
问题原因
你遇到的base64字段序列化后为空对象的核心原因是:
- 你定义的
convertToBase64函数返回的是Promise实例,你在onDrop中直接将Promise赋值给了base64字段,存入redux-form的不是最终的base64字符串,而是Promise对象本身 - JSON序列化规则中,没有特殊处理的Promise实例会被序列化为空对象
{} - 你在控制台看到Promise已经resolved,是浏览器控制台对对象打印的延迟求值特性导致的:你点开对象查看属性时,Promise已经执行完毕,但实际存入表单、提交序列化时,Promise还处于pending状态,或本身无法被JSON序列化
修复方案
方案1:修改onDrop逻辑,等待base64生成完成后再更新表单值
将onDrop改为异步逻辑,等待所有文件的base64转换完成后,再调用onChange更新redux-form的值:
const onDrop = async (file) => { // 等待所有文件的base64转换完成 const processedFiles = await Promise.all(file.map(async fl => { const base64 = await convertToBase64(fl); return Object.assign(fl, { preview: URL.createObjectURL(fl), base64: base64 }) })) onChange(processedFiles); };
修改后存入redux-form的base64字段就是普通字符串,提交时可以正常序列化。
方案2:提交时再转换base64(更推荐,减少redux存储冗余)
不需要在文件上传时就转换base64并存入表单,只需要在提交表单前,统一对选中的文件做base64转换即可:
// 表单提交逻辑示例 const handleSubmit = async (formValues) => { const imageFile = formValues.image[0]; const base64 = await convertToBase64(imageFile); // 构造请求体 const payload = { image: base64, // 其他表单字段 }; await axios.post('/你的上传接口', payload); }
方案3:直接传递二进制文件(性能最优)
如果后端支持multipart/form-data类型的请求,不需要转base64,直接用FormData传递二进制文件,上传性能更高:
const handleSubmit = async (formValues) => { const formData = new FormData(); formData.append('image', formValues.image[0]); // 追加其他表单字段 formData.append('name', formValues.name); await axios.post('/你的上传接口', formData, { headers: { 'Content-Type': 'multipart/form-data' } }); }
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

