关于HTML 请求头 application:x-www-urlencoded

21 min read

HTML 表单中三种类型

  • application/x-www-urlencoded
  • multipart/form-data
  • text-plain

默认情况下是 application/x-www-urlencoded

当表单使用 POST 请求时,数据会被以 x-www-urlencoded 方式编码到 Body 中来传送,
而如果 GET 请求,则是附在 url 链接后面来发送。

"multipart/form-data" 格式

如果要发送大量的二进制数据(non-ASCII)应该使用 "multipart/form-data" 格式。

Content-Type 的类型扩充了multipart/form-data 用以支持向服务器发送二进制数据。

一个典型的 multipart/form-data 请求

POST /t2/upload.do HTTP/1.1
User-Agent: SOHUWapRebot
Accept-Language: zh-cn,zh;q=0.5
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Content-Length: 60408
Content-Type:multipart/form-data; boundary=ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Host: w.sohu.com

--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data; name="city"

Santa colo
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data;name="desc"
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
 
...
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data;name="pic"; filename="photo.jpg"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
 
... binary data of the jpg ...
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC--
  • 包含了多个 Parts
  • Part 头信息中必须包含一个 Content-Disposition 头,其他的头信息则为可选项, 比如 Content-Type 等。
  • Content-Disposition 包含了 type 和 一个名字为 name 的 parameter,type 是 form-data,name 参数的值则为表单控件(也即 field)的名字,如果是文件,那么还有一个 filename 参数,值就是文件名。
  • 如果文件内容是通过填充表单来获得,那么上传的时候,Content-Type 会被自动设置(识别)成相应的格式,如果没法识别,那么就会被设置成 "application/octet-stream"
  • 如果多个文件被填充成单个表单项,那么它们的请求格式则会是 multipart/mixed

测试

这里使用nc 监听 8000,上传文件后显示请求头如下

(base) ➜  ~ nc -l localhost 8000
POST / HTTP/1.1
Host: localhost:8000
Connection: keep-alive
Content-Length: 486
Cache-Control: max-age=0
sec-ch-ua: ".Not/A)Brand";v="99", "Google Chrome";v="103", "Chromium";v="103"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "macOS"
Origin: http://localhost:3000
Upgrade-Insecure-Requests: 1
DNT: 1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryzEteD6Hj9K8KvjKv
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Referer: http://localhost:3000/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en-CN;q=0.8,en;q=0.7,zh-TW;q=0.6


------WebKitFormBoundaryzEteD6Hj9K8KvjKv
Content-Disposition: form-data; name="text"

text default
------WebKitFormBoundaryzEteD6Hj9K8KvjKv
Content-Disposition: form-data; name="file1"; filename="a.txt"
Content-Type: text/plain

Content of a.txt.

------WebKitFormBoundaryzEteD6Hj9K8KvjKv
Content-Disposition: form-data; name="file2"; filename="a.html"
Content-Type: text/html

<!DOCTYPE html><title>Content of a.html.</title>

------WebKitFormBoundaryzEteD6Hj9K8KvjKv--

发送的每个字段部分使用 --boundary 分割开来,最后一行使用 --boundary-- 结尾

关于nc命令

linux可以使用nc命令来测试网络端口是否正常,类似于telnet命令,但也可以用nc命令来监听本地端口,支持TCP、UDP协议,当我们测试NTP服务网络策略是否正常时,可以使用到nc命令测试UDP 123端口。

使用案例如下:

1、测试TCP端口

nc -vz ip tcp-port

2、测试UDP

nc -uvz ip udp-port

3、临时监听TCP端口

nc -l port

4、永久监听TCP端口

nc -lk port

5、临时监听UDP

nc -lu port

6、永久监听UDP

nc -luk port

说明:默认监听的都是TCP端口