使用 POST 请求提交数据的四种方式

261 阅读4分钟

在 HTTP1.1 协议当中规定的 HTTP 请求方法有 OPTIONS,GET,PUT,DELETE,POST,TRACE,HEAD,CONNECT这些,其中 POST 请求一般是用来向服务器提交数据的,下面主要就是讨论 POST 请求提交数据的几种方式

HTTP 协议是以 ASCII 码传输的,是建立在 TCP/IP 协议之上的应用层规范;该规范把 HTTP 请求分为三部分:请求行,请求头和消息主体,如下:

<method> <request-URL> <version>
<headers><entity-body>

协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式。实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的 HTTP 请求满足上面的格式就可以

但是,数据发送出去,还要服务端解析成功才有意义。服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。所以说到 POST 提交数据方案,包含了 Content-Type 和消息主体编码方式两部分。下面就正式开始介绍它们

application/x-www-form-urlencoded

application/x-www-form-urlencodedpost请求对消息主体默认的编码方式,也就是说,如果在页面上你不指定enctype的值,就会使用该编码方式对消息主体进行编码传输

application/x-www-form-urlencoded的编码方式就是常见的 url encode,下面是一个请求的例子:

POST /mock/1025278/cats HTTP/1.1
Host: 127.0.0.1:4523
User-Agent: apifox/1.0.0 (https://www.apifox.cn)
Content-Length: 15
​
name=cat1&age=2 //中间是通过 & 进行连接的,其他字符串是用 url encode 的编码方式

multipart/form-data

multipart/form-data是使用POST传输二进制常用的编码方式,下面是一个上传图片的例子:

POST /mock/1025278/files HTTP/1.1
Host: 127.0.0.1:4523
User-Agent: apifox/1.0.0 (https://www.apifox.cn)
Content-Length: 216
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
​
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="b.jpg"
Content-Type: image/png
​
PNG ... content of b.png ...
------WebKitFormBoundary7MA4YWxkTrZu0gW--

在上面的请求体中可以看到Content-type:multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW,其中Content-type包含了两部分内容:

  • multipart/form-data:指定了消息体的编码方式
  • boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW:分割符,每个部分使用 --boundary 分割开来,最后一行使用 --boundary-- 结尾

该传输方式会将传输的内容分为一个个用由boundary分隔开来独立的部分组成,下面就是其中的一部分的内容:

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="file"; filename="b.jpg"
Content-Type: image/png
​
PNG ... content of b.png ... //这就是该图片的内容

如果传输的文件能够被自动识别,那么就会有Content-Type: image/png,否则就会被设置为application/octet-stream就是表示传输的内容为二进,但没有指明具体是什么类型,例如:

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data;name="a"; filename="a.jpg"
Content-Type: application/octet-stream
Content-Transfer-Encoding: binary
​
...contents of a.jpg...

如果每一部分的内容和默认的编码方式不同,那么就会使用"content-transfer-encoding"来指定这一部分的编码方式,比如:

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: f; filename="f.gif"
Content-Type: image/gif
Content-Transfer-Encoding: binary
​
...contents of f.gif...

如果没有指定Content-Type的话,默认就是Content-Type:text/plain,如下所示的这种就是

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="name"
​
zhangsan

如果传输的是文件,还会包含Content-Disposition: form-data; name="file"; filename="b.jpg",其中Content-Disposition是用来指示用户代理如何显示附加文件的,如果是attachment就意味着消息体应该被下载到本地,通常浏览器会出现一个保存的对话框,如果是inline则表示消息体会以页面的一部分展示

如果Disposition作为multipart body的消息头时,第一个参数始终为form-data,后面的两个分别为文件的名称和文件的路径,如:

Content-Disposition: form-data; name="f1"; filename="f1.txt"

application/json

application/json应该是目前使用POST创建一个对象常用的方式,下面是一个例子:

POST /mock/1025278/users HTTP/1.1
Host: 127.0.0.1:4523
User-Agent: apifox/1.0.0 (https://www.apifox.cn)
Content-Type: application/json
Content-Length: 56
​
{
    "username": "毛刚",
    "email": "b.knjvds@qq.com"
}

消息头和消息体之间有一个空行进行分割

text/xml

text/xml是一种使用xml编码的方式进行数据传输的方法,下面是一个例子:

POST /mock/1025278/users HTTP/1.1
Host: 127.0.0.1:4523
User-Agent: apifox/1.0.0 (https://www.apifox.cn)
Content-Type: application/xml
Content-Length: 65
​
<?xml version="1.0" encoding="UTF-8"?>
<a>
  <b>cc</b>
</a>

参考连接:imququ.com/post/four-w…