Vue3+Zodios+Zod多文件上传报错:无效Body参数
问题解决:Vue3 + Zodios 多文件上传校验失败与上传内容异常
核心问题分析
- 类型不匹配:你的Zod Schema定义的是
z.array(z.instanceof(File)),但代码中将File对象转成了Base64字符串,直接导致Zod静态校验失败,触发Zodios: Invalid Body parameter 'body'警告。 - FormData处理不当:Zodios设置了
requestFormat: 'form-data',但提交的是包含Base64字符串的普通JS对象,既不符合校验规则,也无法被正确解析为文件上传请求。
分步解决方案
1. 移除Base64转换,直接使用原生File对象
既然Schema要求的是File实例数组,直接收集原生File对象即可,无需转换:
async function submit(event){ // 将FileList转换为数组,保留原生File对象 const fileList = file_input.value?.files ? Array.from(file_input.value.files) : [] // 提交符合Schema类型要求的参数 await api.post('some_rest_endpoint/', { file: fileList }) }
2. 适配后端接收规则,手动构建FormData(可选)
如果后端要求文件数组以file[]作为参数名接收(如Django、Flask等框架),手动构建FormData能避免Zodios自动转换的不确定性:
async function submit(event){ const formData = new FormData() const files = file_input.value?.files if (files) { // 循环添加文件,用`file[]`作为键名适配后端数组接收逻辑 Array.from(files).forEach(file => { formData.append('file[]', file) }) } // 提交FormData实例 await api.post('some_rest_endpoint/', formData) }
此时需同步调整Zod Schema以适配FormData:
// 自定义FormData校验规则,确保包含有效的File数组 const multi_file_schema = z.custom<FormData>(formData => { const files = formData.getAll('file[]') return files.every(item => item instanceof File) }, { message: 'FormData必须包含有效的File对象数组' })
3. 调整Zodios API定义
保持requestFormat: 'form-data'以确保Zodios正确处理文件上传请求,参数Schema对应调整后的校验规则:
api = makeApi({ method: 'post', path: 'some_rest_endpoint/', requestFormat: 'form-data', parameters: [ { name: 'body', type: 'Body', schema: multi_file_schema, }, ], response: z.object({ /* 后端返回结构对应的Schema */ }), })
关键注意事项
- 若后端明确要求接收Base64格式的文件,需同步修改Zod Schema为
z.array(z.string()),并保留Base64转换逻辑。 - 后端接收文件的参数名需与前端提交的键名完全一致,否则会出现文件接收失败的情况。
内容的提问来源于stack exchange,提问作者Waqar Ali
相关产品推荐
相关产品推荐

