1. HTTP 协议概览
1.1. HTTP 不同版本的差异和特征
- HTTP1.0: 明文、无连接
- HTTP1.1:
- 支持持久化(
Keep-Alive
)操作(发送往 HTTP 协议后,连接不关闭) - Pipeline(同时发多个请求,但也存在队头阻塞问题)
- 支持分块
- 支持持久化(
- HTTP2.0: 改进性能和效率
- 二进制 Stream 协议,可以对请求和响应进行优先级排序和流量控制
- 多路复用(连接复用,复用底层同一个 TCP 连接,避免队头阻塞问题)
- 头部压缩(降低了传输开销)
- 支持服务端 Push 推送资源
1.2. HTTP 协议内容
- 请求:HTTP 请求行、HTTP 请求头、HTTP 请求体
- 响应:HTTP 响应行、HTTP 响应头、HTTP 响应体
|
|
1.3. HTTP 协议请求方式
- GET、POST、HEAD、OPTIONS、DELETE、PUT、TRACE、CONNECT
1.4. HTTPS 和 TCP 以及 SSL
HTTP 属于应用层协议,依托与底层 TCP/IP 协议栈支持,在发送 HTTP 请求之前,需要先建立连接;考虑到传输安全,引入安全 SSL 来支持(会话层),即 HTTPS 协议
POST 和 GET 请求差异
GET 请求
- 用于获取资源
- 参数和值显示在 URL 中
- 适合非敏感信息
- 有长度限制
- 可以被缓存和保存
POST 请求:
- 用于提交数据
- POST请求将参数和值包含在请求的正文中,而不是URL中,请求的内容类型(Content-Type)通常设置为
application/x-www-form-urlencoded
或multipart/form-data
,以及application/json
- 适合敏感信息
- 没有长度限制
- 不会被缓存和保存
2. POST 请求
2.1. POST 内容和编码
协议规定POST
提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式。实际上,开发者完全可以自己决定消息主体的格式,只要最后发送的HTTP
请求满足协议格式就可以。
但是,数据发送出去,还要服务端解析成功才有意义。
一般服务端语言如 php、python 等,以及它们的 framework,都内置了自动解析常见数据格式的功能。
服务端通常是根据请求头(headers)中的Content-Type
字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。所以说到POST
提交数据方案,包含了Content-Type
和消息主体编码方式
两部分。
2.2. 表单数据请求
最常见的表单请求,参考:https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4
- 确定表单的内容(包含
disbaled
、submit
、checkbox
、radio
、select
- 构建表单数据集
- 针对表单数据集,基于
content-type
指定数据集的编码方式(由 form 表单的enctype
属性指定)- 内容编码默认采用:
application/x-www-form-urlencoded
表单 url 编码,相比于块编码,效率更低,适合明文 ASCII 码 - 内容编按码块编码:
multipart/form-data
,多用于文件,非 ascii 数据编码,其遵循multipart MIME data streams
规则,每个 part 部分包含Content-Type
、Content-Disposition
,参考后续示例
- 内容编码默认采用:
- 最后提交被编码的数据集:通过
action
、method
发送给到具体的应用处理代理- get 请求:参数通过
?
追加到action
上,然后后续接数据集,编码通过application/x-www-form-urlencoded
编码,且仅限制在ASCII码
- post 请求:参数通过 form 表单的
enctype
属性指定
- get 请求:参数通过
3. POST Content-Type 类型
HTTP 协议,在请求过程中,支持不同的Content-Type
类型,常见的有text/plain
, application/json
, application/xml
, application/x-www-form-urlencoded
, multipart/form-data
3.1. application/x-www-form-urlencoded
最常见的POST
提交数据的方式,默认数据基于 urlencode,相比于块编码,效率更低,适合明文 ASCII 码。Ajax 请求,也是用的这种方式,Content-Type
默认值都是application/x-www-form-urlencoded;charset=utf-8
。
|
|
3.2. multipart/form-data
关键点:有边界boundary
、适用于大文件传输(大文本、二进制文件)、FORM 表单开启enctype=multipart/form-data
选项
通过指定 enctype="multipart/form-data"
进行分块传输(在有 files 控件时候一定需要)
|
|
户输入 Larry 和上传了一张图片
|
|
3.3. application/json
现在越来越多的人把它作为请求头,用来告诉服务端消息主体是序列化后的 JSON 字符串。JSON 格式支持比键值对复杂得多的结构化数据,服务端基本都支持 JSON,适合RESTFUL
风格接口。
部分语言如果不支持原生解析,需要一定处理,比如 PHP 在请求头中Content-Type
为application/json
时,从php://input
里获得原始输入流,再json_decode
成数组对象。
|
|