周分享

HTTP全知道(上)

2020-03-28  本文已影响0人  橙汁坤

你所需要了解的关于http的一切

HTTP 报文结构

起始行 + 头部 + 空行 + 实体

POST /home HTTP/1.1

返回报文格式起始行也叫做状态行,由http版本、状态码和原因三部分组成,
在起始行中,每两个部分之间用空格隔开,最后一个部分后面应该接一个换行。

HTTP/1.1 200 OK

HTTP 的请求方法

常用的有:


  1. GET 请求会被浏览器缓存下来,留下历史记录,而 POST 默认不会。
  2. GET 只能进行 URL 编码,只能接收 ASCII 字符,而 POST 没有限制。
  3. GET 一般放在 URL 中,因此不安全,POST 放在请求体中,更适合传输隐私信息。
  4. GET 请求会把请求报文一次性发出去,而 POST 会分为两个 TCP 数据包,首先发 header 部分,如果服务器响应, 然后发 body 部分。

URI 结构

image.png

HTTP 状态码

RFC 规定 HTTP 的状态码为三位数,被分为五类:

1xx: 表示目前是协议处理的中间状态,还需要后续操作。在HTTP升级为WebSocket的时候,如果服务器同意变更,就会发送状态码 101。
2xx: 表示成功状态。

3xx: 重定向状态,资源位置发生变动,需要重新请求。

4xx: 请求报文有误。

5xx: 服务器端发生错误。

HTTP 的特点

HTTP 缺点

HTTP压缩方式

对数据进行编码压缩的,压缩方式就体现在了发送方的Content-Encoding字段上, 同样的,接收什么样的压缩方式体现在了接受方的Accept-Encoding字段上。

gzip: 当今最流行的压缩格式
deflate: 另外一种著名的压缩格式
br: 一种专门为 HTTP 发明的压缩算法

// 发送端
Content-Encoding: gzip
// 接收端
Accept-Encoding: gizp

HTTP字符集

在接收端对应为Accept-Charset,指定可以接受的字符集,而在发送端并没有对应的Content-Charset, 而是直接放在了Content-Type中,以charset属性指定。

// 发送端
Content-Type: text/html; charset=utf-8
// 接收端
Accept-Charset: charset=utf-8

HTTP 对于定长和不定长的数据传输的

chunk长度(16进制的数)
第一个chunk的内容
chunk长度(16进制的数)
第二个chunk的内容
......
0

HTTP 处理大文件传输

对于大文件来说,一次性全部传输显然是不现实的,会有大量的等待时间,严重影响用户体验。因此,HTTP 采取了范围请求来解决允许客户端仅仅请求一个资源的一部分。要支持这个功能,就必须加上这样一个响应头:Accept-Ranges: none来告知客户端这边是支持范围请求。

// 单段数据
Range: bytes=0-9
// 多段数据
Range: bytes=0-9, 30-39
HTTP/1.1 206 Partial Content
Content-Length: 10
Accept-Ranges: bytes
Content-Range: bytes 0-9/100

Content-Range字段,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

在响应体中各段数据之间会由这里指定的分隔符分开,而且在最后的分隔末尾添上--表示结束。

HTTP 中如何处理表单数据的提交?

在 http 中,有两种主要的表单提交的方式,体现在两种不同的Content-Type取值:

  1. 其中的数据会被编码成以&分隔的键值对
  2. 字符以URL编码方式编码。
// 转换过程 -> 如下(最终形式)
前: {a: 1, b: 2} -> a=1&b=2
后:"a%3D1%26b%3D2"
  1. 请求头中的Content-Type字段会包含boundary,且boundary的值有浏览器默认指定。例:Content-Type: multipart/form-data;boundary=----WebkitFormBoundaryRRJKeWfHPGrS4LKe
    数据会分为多个部分,每两个部分之间通过分隔符来分隔。

相应的请求体是下面这样:

Content-Disposition: form-data;name="data1";
Content-Type: text/plain
data1
----WebkitFormBoundaryRRJKeWfHPGrS4LKe
Content-Disposition: form-data;name="data2";
Content-Type: text/plain
data2
----WebkitFormBoundaryRRJKeWfHPGrS4LKe--
  1. 每一个表单元素都是独立的资源表述。在平时的调试中,可能并没有注意到其中还有boundary的存在,之所以在平时感觉不到,是以为浏览器和 HTTP 给你封装了这一系列操作。
  2. 在实际的场景中,对于图片等文件的上传,基本采用multipart/form-data而不用application/x-www-form-urlencoded,因为没有必要做 URL 编码,带来巨大耗时的同时也占用了更多的空间。
上一篇 下一篇

猜你喜欢

热点阅读