React项目fetch替代axios上传文件时后端split报错排查
问题根因
- 后端报错
Cannot read property of split of undefined的直接原因是接口拿不到filename字段:执行const filename = request.payload.filename时得到undefined,后续调用filename.split()自然抛出异常。 - 问题出在fetch的请求写法有两个致命错误:
- 手动设置请求头
Content-Type: application/json,和文件上传需要的multipart/form-data类型完全不匹配 - 把存储文件和文件名的FormData对象用
JSON.stringify()转成JSON字符串传递,FormData是特殊的浏览器接口对象,序列化后根本不会保留你append进去的file、filename字段,后端解析payload自然拿不到任何参数
- 手动设置请求头
- 之前axios版本能正常运行,是因为axios自带适配逻辑:当检测到传入的data是FormData实例时,会自动覆盖你手动写的Content-Type头,改成正确的
multipart/form-data并自动拼接boundary分隔符,同时直接发送FormData二进制内容,不会做多余的序列化处理。而fetch没有这类自动适配逻辑,完全按照你手动写的配置发请求,才会触发问题。
修复方法
修改fetch请求配置,遵循FormData上传的规则即可:
- 删掉手动设置的
Content-Type请求头,浏览器会自动识别body是FormData类型,自动补全正确的multipart/form-data头和对应的boundary参数,手动设置反而会丢失boundary导致后端解析失败 - 去掉
JSON.stringify()处理,直接把FormData实例作为body的值传递
修正后的请求代码如下:
return fetch(`${NewHostName}/upload`, { method: "post", headers: { Authorization: localStorage.getItem('authToken'), }, body: data, }) .then((res) => { return res.json(); }) .then((payload) => { return payload; }) .catch((err) => { console.log("err", err) throw err; })
额外注意项
- 确认Upload组件绑定的
dummyRequest自定义上传方法没有修改原始file对象的结构,保证append到FormData中的是原生File实例,否则后端可能无法正确读取文件内容 - 如果后续要加其他请求头,只加业务需要的(比如鉴权头)即可,不要手动干预Content-Type的设置
内容的提问来源于stack exchange,提问作者Profer
相关产品推荐
相关产品推荐

