使用S3预签名URL上传CSV返回200但文件为空问题排查
S3预签名URL上传CSV为空文件问题修复
问题根源
你传入axios的请求体不是原生File实例,而是包裹了File的普通JS对象。
你在handleUpload里执行setFileData({ file })时,把选中的文件存在了状态对象的file字段下,后续调用上传函数时如果直接传整个fileData对象,axios会默认尝试把普通对象序列化为JSON,而File实例无法被JSON序列化,最终请求体里只会剩下空的file: {}结构,S3接收到的就是无实际内容的空请求,最终生成的11字节文件就是序列化后的空对象残留内容,和你在请求负载里看到的现象完全吻合。
修复步骤
- 上传时传入原生File实例,不要传外层包裹对象:调用
uploadFile时,参数传fileData.file而不是整个fileData对象 - 调整axios配置,禁止自动序列化二进制文件,移除不必要的请求头
- 校验请求负载,确认上传时请求体为二进制内容而非普通对象结构
修正后的代码示例:
// 调用上传函数时注意取到真实File对象 // 示例:拿到预签名url后的调用逻辑 uploadFile(presignedUrl, fileData.file)
const uploadFile = (url, uploadFile) => { // 入参uploadFile必须是input选中的原生File/Blob实例 return axios .put(url, uploadFile, { headers: { "Content-Type": "text/csv" // 移除Accept: application/json头,S3预签名上传不需要JSON格式响应,多余头可能触发跨域或签名校验异常 }, // 强制关闭axios的自动JSON序列化,直接传输二进制内容 transformRequest: [(data) => data] }) .then((res) => res.data) .catch((err) => { console.error('上传请求异常', err); throw err; }); };
改完后可在浏览器开发者工具的网络面板校验:上传请求的Payload应该显示为二进制内容(标注为(binary)),不再出现file: {}的键值对结构,上传完成后S3存储桶内的文件大小会和本地CSV文件实际大小一致。
内容的提问来源于stack exchange,提问作者Brian Wang
相关产品推荐
相关产品推荐

