JS使用FormData上传文件为application/octet-stream,如何设置为multipart/form-data
问题解答
你不需要手动设置multipart/form-data请求头,你当前的代码本身已经在发送multipart/form-data格式的请求了。
原理说明
- 当fetch的
body参数直接传入FormData实例时,浏览器会自动完成两项配置:- 自动给请求头添加
Content-Type: multipart/form-data; boundary=xxxx属性,其中boundary是浏览器自动生成的随机分隔符,用来区分表单内的不同字段。如果你手动指定该请求头,反而会覆盖浏览器生成的boundary信息,导致后端无法正常解析表单。 - 你观察到的
application/octet-stream是文件对应的单个表单字段的Content-Type,属于multipart表单内部单个部分的属性,不是整个请求的Content-Type,这个默认值不会影响Spring后端正常解析文件。
- 自动给请求头添加
代码优化建议
- 上传文件时不要传本地绝对路径作为文件名,直接使用用户上传的原文件名即可,避免后端拿到的文件名带冗余路径:
upload() { let formData = new FormData(); // 替换第三个参数为原文件名 formData.append("file", this.data.file.file, this.data.file.filename); formData.append("request", JSON.stringify(request)); let reqOptions = { method: 'POST', body: formData // 不要手动加Content-Type头 } fetch('http://127.0.0.1:8081/multi-mt-evaluation/report', reqOptions) .then(response => response.json()) .then(data => console.log(data)); }
- 如果确实需要指定文件部分的MIME类型,可以通过构造Blob对象实现,示例如下:
const fileWithMime = new Blob([this.data.file.file], { type: 'application/x-xliff+xml' }); formData.append("file", fileWithMime, this.data.file.filename);
后端对应接收代码
Spring侧直接用MultipartFile接收即可,无需额外配置:
@PostMapping("/multi-mt-evaluation/report") public R handleReport(@RequestParam("file") MultipartFile file, @RequestParam("request") String requestJson) { // 序列化requestJson、处理文件的业务逻辑 }
内容的提问来源于stack exchange,提问作者egzaell
相关产品推荐
相关产品推荐

