multipart/form-data

手动设置Content-Type: multipart/form-data报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
changeUserAvatar(authParam, file) {
let formData = new FormData();
//file is actually new FileReader.readAsDataURL(myId.files[0]);
formData.append('profile_image', file);

fetch(BASE_URL + 'profile-image', {
method: 'POST',
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': authParam
},
body: formData
}).then((response) => {
return response.json();
}).then((response) => {
debugger;
}).catch((error) => {
console.error(error);
});
}

错误信息

Error: profile_image can not be blank

原因

手动设置Content-type = multipart/form-data,意味着缺少了boundary参数,这里不需要手动设置,Fetch会根据FormData的内容自动生成Content-type,像下面这样:

1
Content-Type: multipart/form-data;boundary=----WebKitFormBoundaryyrV7KO0BoCBuDbTL

延伸

如果你想发送下面的数据到服务器:

1
2
name = John
age = 12
  1. 使用application/x-www-form-urlencoded方式,会这样发送:
1
name=John&age=12

如你所见,服务器知道用&来分割参数,如果参数值里面有&字符,则需要经过encode来编码一下参数再传递。

  1. 使用multipart/form-data方式,服务器如何知道用什么字符来分割参数呢。

使用boundary,所以发送的格式像下面这样:

1
2
3
4
5
6
7
8
9
10
11
Content-Type: multipart/form-data; boundary=XXX

--XXX
Content-Disposition: form-data; name="name"

John
--XXX
Content-Disposition: form-data; name="age"

12
--XXX--