GET/POST
- 缓存角度: GET 会主动缓存,POST 默认不会
- 编码: GET 只能进行 URL 编码,接收 ASCII 字符,POST 没有限制
- 参数: GET 放在 URL 中,POST 放在请求体中
- 幂等: GET 是幂等,POST 不是。(幂等:表示执行相同的操作,结果也是相同的)
- tcp: GET 会一次性发出去,POST 会分为两次,第一次发送 Header,服务器响应 100(continue),然后发 body 部分
HTTP 特点
- 灵活可扩展,一、语义上的自由,只定义了基本格式,二、传输的多样性(文本、视频、图片)
- 可靠传输(基于 TCP、IP)
- 请求-应答
- 无状态
HTTP 缺点
无状态
长连接场景,需要保存大量的上下文信息,以避免传输大量重复信息
明文传输
协议里的报文使用的是文本形式
队头阻塞
当开启长连接时,共用一个 TCP 连接,同一时刻只能处理一个,当前请求耗时过长的情况下,其他的请求只能处于阻塞状态
Accept
数据格式 Accept
- text: text/html,text/plain,text/css
- image: image/gif,image/png,image/jpeg 等
- audio/video: audio/mpeg,video/mp4 等
- application: application/json,application/javascript,application/pdf,application/octet-stream
压缩方式
- Content-Encoding // 响应
- Accept-Encoding // 请求
- 压缩方式: gzip、deflate、br
支持语言
- Content-Language // 响应
- Accept-Language // 请求
字符集
- Accept-Charset // 请求
- 响应没有对应的 Content-Charset
- Content-Type: text/html;charset=utf-8 // 而是放在了 Content-Type 中,以 charset 指定
总结
定长和不定长传输
Content-Length
定长包体,设置不正确可能无法显示Transfer-Encoding: chunked
,分块传输,基于长连接持续推送
大文件传输
前置条件
- 服务器支持
- 添加响应头
Accept-Ranges: none
Range 字段拆解
格式:Range: x-y
- 0-499 表示从开始到 499 个字节
- 500- 表示从第 500 字节到终点
- -100 表示文件最后的 100 个字节
服务器收到请求后验证范围是否合法,越界返回 416 错误码,否则读取相应片段,返回 206 状态码。
同时服务器需要添加 Content-Range 字段,跟请求头中 Range 字段有所不同。
具体来说,请求
单段数据
和请求多端数据
,响应头是不一样的 - Range: bytes=0-9
- Range: bytes=0-9,20-30
单段数据
HTTP/1.1 206 Partial Content
Content-Length: 10
Accept-Ranges: bytes
Content-Range: bytes 0-9/100
xxxxx
0-9 表示请求的返回,100 表示总资源的大小
多段数据
HTTP/1.1 206 Partial Content
Content-Type: multipart/byteranges; boundary=00000010101
Content-Length: 189
Connection: keep-alive
Accept-Ranges: bytes
--00000010101
Content-Type: text/plain
Content-Range: bytes 0-9/96
i am xxxxx
--00000010101
Content-Type: text/plain
Content-Range: bytes 20-29/96
eex jspy e
--00000010101--
关键字段 Content-Type: multipart/byteranges; boundary=00000010101 代表的信息量
- 请求一定是多段数据
- 响应体中的分隔符是 00000010101
- 末尾分隔符—表示结束
如何处理表单的提交
application/x-www-form-urlencoded
- 数据会被编码为&分隔的键值对
- 字符以 URL 编码方式编码
multipart/form-data
- 请求头 Content-Type 字段中包含 boundary,boundary 的值由浏览器指定
- 多个部分的数据,每两个部分通过分隔符来分隔,每部分描述均有 HTTP 描述子体包,分隔符最后加上—表示结束
Content-Disposition: form-data;name="data1";
Content-Type: text/plain
data1
----WebkitFormBoundaryRRJKeWfHPGrS4LKe
Content-Disposition: form-data;name="data2";
Content-Type: text/plain
data2
----WebkitFormBoundaryRRJKeWfHPGrS4LKe--
HTTP1.1 如何解决队头阻塞问题
什么是 HTTP 队头阻塞
http 传输是基于请求-应答模式,报文必须是一发一收,值得注意的是,里面的任务放在一个任务队列中串行执行,一旦队首请求处理太慢,就会阻塞后面请求的处理,这就是著名的队头阻塞问题。
并发连接
同一个域名允许分配多个长连接,相当于增加了任务队列,不至于一个队伍的任务阻塞其他所有任务。RFC2616 中规定,客户端最多并发 2 个连接,但浏览器实现不一致,chrome 是 6 个
域名分片
一个域名可以并发 6 个连接,多分出几个域名可以增加并发的长连接数,很好的解决了队头阻塞问题