skip to content
天真笔录

HTTP灵魂之问

/ 5 min read

GET/POST

  1. 缓存角度: GET 会主动缓存,POST 默认不会
  2. 编码: GET 只能进行 URL 编码,接收 ASCII 字符,POST 没有限制
  3. 参数: GET 放在 URL 中,POST 放在请求体中
  4. 幂等: GET 是幂等,POST 不是。(幂等:表示执行相同的操作,结果也是相同的)
  5. tcp: GET 会一次性发出去,POST 会分为两次,第一次发送 Header,服务器响应 100(continue),然后发 body 部分

HTTP 特点

  1. 灵活可扩展,一、语义上的自由,只定义了基本格式,二、传输的多样性(文本、视频、图片)
  2. 可靠传输(基于 TCP、IP)
  3. 请求-应答
  4. 无状态

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

压缩方式

  1. Content-Encoding // 响应
  2. Accept-Encoding // 请求
  3. 压缩方式: gzip、deflate、br

支持语言

  1. Content-Language // 响应
  2. Accept-Language // 请求

字符集

  1. Accept-Charset // 请求
  2. 响应没有对应的 Content-Charset
  3. Content-Type: text/html;charset=utf-8 // 而是放在了 Content-Type 中,以 charset 指定

总结

Accept

定长和不定长传输

  1. Content-Length定长包体,设置不正确可能无法显示
  2. Transfer-Encoding: chunked,分块传输,基于长连接持续推送

大文件传输

前置条件

  1. 服务器支持
  2. 添加响应头 Accept-Ranges: none

Range 字段拆解

格式:Range: x-y

  1. 0-499 表示从开始到 499 个字节
  2. 500- 表示从第 500 字节到终点
  3. -100 表示文件最后的 100 个字节 服务器收到请求后验证范围是否合法,越界返回 416 错误码,否则读取相应片段,返回 206 状态码。 同时服务器需要添加 Content-Range 字段,跟请求头中 Range 字段有所不同。 具体来说,请求单段数据和请求多端数据,响应头是不一样的
  4. Range: bytes=0-9
  5. 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 代表的信息量

  1. 请求一定是多段数据
  2. 响应体中的分隔符是 00000010101
  3. 末尾分隔符—表示结束

如何处理表单的提交

application/x-www-form-urlencoded

  1. 数据会被编码为&分隔的键值对
  2. 字符以 URL 编码方式编码

multipart/form-data

  1. 请求头 Content-Type 字段中包含 boundary,boundary 的值由浏览器指定
  2. 多个部分的数据,每两个部分通过分隔符来分隔,每部分描述均有 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 个连接,多分出几个域名可以增加并发的长连接数,很好的解决了队头阻塞问题