jQuery ajax 文件上传 Request Headers 缺少 boundary

jquery 文件上传,一个奇葩的坑,也可能是我使用姿势不对,挖出来的坑。如下:

一般上传方式

1
2
3
4
5
6
7
8
9
10
11
12
13
const file = document.getElementById('js_resume_file').files[0];
const formData = new FormData();
formData.append('file', file);
$.ajax({
type: 'POST',
url: 'api',
data: formData,
contentType: 'multipart/form-data',
processData: false,
success: function (data) {
console.log('上传完毕');
},
});

如果代码是以上方式,大概率后端接口会报错 500。但是后端自测接口正常!

详细对比正常上传的 Network ,会发现 Request Headers 字段 Content-Type 不同,缺少了 boundary 字段。并且携带数据也不一样,Form Data 变成了 Request Payload

自测接口正常的 Content-Type 如下:

1
2
3
4
5
Request Headers
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryInLo99EGvBmy5YZN

Form Data
file: (binary)

500 错误的 Content-Type 如下:

1
2
3
4
5
6
7
8
9
10
Request Headers
Content-Type: multipart/form-data

Request Payload
------WebKitFormBoundaryZ1vno04nVnWqUY5K
Content-Disposition: form-data; name="file"; filename="test.jpg"
Content-Type: image/jpeg


------WebKitFormBoundaryZ1vno04nVnWqUY5K--

处理方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const file = document.getElementById('js_resume_file').files[0];
const formData = new FormData();
formData.append('file', file);
$.ajax({
type: 'POST',
url: 'api',
data: formData,
- contentType: 'multipart/form-data',
+ contentType: false,
processData: false,
success: function (data) {
console.log('上传完毕');
},
});

处理方式很简单,将 contentType: false 即可。

原因:jquery ajax 源码中有一段这代码:

1
2
3
4
// Set the correct header, if data is being sent
if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
jqXHR.setRequestHeader( "Content-Type", s.contentType );
}

如果你手动设置了 contentType ,那么就用你设置的值来处理 Request Headers ,所以还是老实的设置为 false 吧!

本文由 linx(544819896@qq.com) 创作,采用 CC BY 4.0 CN协议 进行许可。 可自由转载、引用,但需署名作者且注明文章出处。本文链接为: https://blog.jijian.link/2020-07-28/jquery-ajax-upload-file/

如果您觉得文章不错,可以请我喝一杯咖啡!