文章目录
- Intro
- 错误原因 & 解决
- 正确的前端请求方式 MDN
Intro
前端使用 form 提交文件到后端。
使用 jquery/axios/fetch 或其他HTTP客户端程序发送HTTP请求,但是后端(Spring框架)报错如下:
Request processing failed; nested exception is org.springframework.web.multipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
复制
错误原因 & 解决
我是因为设置了 "Content-Type": "multipart/form-data"
这样的头,才会失败。
这个请求头的格式样例(见https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type):
POST /foo HTTP/1.1 Content-Type: multipart/form-data; boundary=---------------------------974767299852498929531610575 ...
复制
其中 multipart/form-data
表示请求内容的数据类型,而后的 boundary和值表示发送数据的边界(用于确定文件何时结束 EOF)。
那我加上 boundary 参数?
可是 boundary 的值是由上传文件的大小影响的,我怎么去确定啊?
答案是不用确定。
(程序员)不要发送 Content-Type
这个请求头。
ref: https://stackoverflow.com/questions/35192841/how-do-i-post-with-multipart-form-data-using-fetch
make sure not to set the Content-Type header. The browser will set it for you, including the boundary parameter. 一定不要在发送请求的时候自己用javascript去设置 Content-Type 头! 浏览器会替你自动设置这个请求头的值(包括 bounday 参数)!
复制
正确的前端请求方式 MDN
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#uploading_a_file
const formData = new FormData(); const fileField = document.querySelector('input[type="file"]'); formData.append('username', 'abc123'); formData.append('avatar', fileField.files[0]); fetch('https://example.com/profile/avatar', { method: 'PUT', // headers: { // "Content-Type": "multipart/form-data" // 我们手动加这个header会导致错误,让浏览器自己去设置这个header即可! // }, body: formData }) .then((response) => response.json()) .then((result) => { console.log('Success:', result); }) .catch((error) => { console.error('Error:', error); });
复制