HTTP协议multipart/form-data文件上传

HTTP multipart/form-data file upload

Posted by alovn on February 13, 2023

x-www-form-urlencoded

x-www-form-urlencoded会将表单里的数据转为使用&作为分隔符的键值对传输, 比如下面提交的name和age两个参数:

1
2
3
4
5
6
POST /upload HTTP/1.1
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded
Content-Length: 15

name=abc&age=18

form-data

HTTP协议中通过 multipart/form-data 表单提交数据,既可以是普通的键值对, 也可以上传文件。以下示例是通过form-data提交name和age参数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
POST /upload HTTP/1.1
Host: localhost:8080
Content-Length: 230
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryNzHzdPblHRjhphc0

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

abc
------WebKitFormBoundaryNzHzdPblHRjhphc0
Content-Disposition: form-data; name="age"

18
------WebKitFormBoundaryNzHzdPblHRjhphc0--

上面的请求头中的 Content-Type 指定了传输格式为multipart/form-data,同时指定了分割符参数boundary,用于分割不同的参数。

Content-Disposition 用于字段的描述信息,指定了参数名,后端可以通过该参数名获取到对应的值。

正是由于boundary参数的分割可以提交不同的参数,除了提交键值对,还可以用于上传文件,当然也可以是多个文件。

下面的示例通过form-data同时提交参数和文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
POST /upload HTTP/1.1
Host: localhost:8080
Content-Length: 375
Content-Type: multipart/form-data; boundary=----WebKitFormBoundarytJdAZC57RltjMWwR

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

abc
------WebKitFormBoundarytJdAZC57RltjMWwR
Content-Disposition: form-data; name="age"

18
------WebKitFormBoundarytJdAZC57RltjMWwR
Content-Disposition: form-data; name="file"; filename="hello.txt"
Content-Type: text/plain

hello

------WebKitFormBoundarytJdAZC57RltjMWwR--

Content-Disposition 指定了参数名和文件名,Content-Type 指定了文件类型。