阅读手札 | 手把手带你探索『图解 HTTP』

阅读手札 | 手把手带你探索『图解 HTTP』

前言

本文已经收录到我的 Github 个人博客,欢迎大佬们光临寒舍:

我的 Github 博客

学习清单:

一、网络基础 TCP/IP

通常使用的网络(包括互联网)是在 TCP/IP 协议族的基础上运作,而 HTTP 属于它内部的一个子集

1.1 层次划分

  • 应用层: 决定了向用户提供应用服务时通信的活动,比如 FTPDNSHTTP

易记:应用层,顾名思义,是提供给应用服务的活动,然后现在最火的应用是微信(通信功能),所以就是:向用户提供应用服务时通信

  • 传输层: 对上层应用层提供处于网络连接中的两台计算机之间的数据传输,比如 TCPUDP

易记:传输层,顾名思义,提供计算机之间的数据传输

  • 网络层: 用来处理在网络上流动的数据包,该层规定了通过怎样的路径到达对方计算机,并把数据包传送给对方;与对方计算机之间通过多台计算机或网络设备进行传输时,网络层所起的作用就是在众多的选项内选择一条传输路线

易记:网络层,顾名思义,处理在网络上流动的数据包,规定通过什么路径

  • 数据链路层: 用来处理连接网络的硬件部分

易记:数据链路层,顾名思义,链路偏硬件的东西,而数据是偏软件层面的东西,自然可以想到是起到连接作用

1.2 通信的过程

  1. 首先作为发送端的客户端在应用层HTTP 协议)发出获取 Web 页面的 HTTP 请求
  2. 接着,为了传输方便,在传输层TCP 协议)把从应用层处收到的数据(HTTP 请求报文)进行分割,并在各个报文上打上标记序号及端口号后转发给网络层
  3. 网络层IP 协议),增加作为通信目的地MAC 地址后转发给链路层。这样一来,发往网络的通信请求就准备齐全了
  4. 接收端的服务器在链路层接收到数据,按序往上层发送,一直到应用层。当传输到应用层,才能算真正接收到由客户端发送过来的 HTTP 请求

image-20200707164153058

1.3 三次握手

之前已经笔者已经写了,因此在这里就不再赘述,点击链接即可跳转:TCP 连接管理

1.4 各协议与 HTTP 协议的关系

image-20200707164806629

1.5 URI 和 URL

Q1:URLURI 的区别

  • URI 用字符串标识某一互联网资源
  • URL 表示资源的地点

由此可见, URLURI 的子集

Q2:URI 的各部分结构

image-20200707181219904

二、简单的 HTTP 协议

2.1 HTTP 方法

  • GET 获取资源: 用来请求访问已被 URI 识别的资源,指定的资源经服务器端解析后返回响应内容
  • POST 传输实体主体: 用来传输实体的主体 虽然用 GET 方法也可以传输实体的主体,但一般不用 GET 方法进行传输,而是用 POST 方法
  • PUT 传输文件: 在请求报文的主体中包含文件内容,然后保存到请求 URI 指定的位置 鉴于 HTTP1.1PUT 方法自身不带验证机制,任何人都可以上传文件,存在安全性问题,因此一般不使用该方法
  • HEAD 获得报文首部:GET 方法一样,只是不返回报文主体部分。 用于确认 URI 的有效性及资源更新的日期时间等
  • DELETE 删除文件: 用来删除文件,是与 PUT 相反的方法。DELETE 方法按请求 URI 删除指定的资源。 不带验证机制,所以一般不使用 DELETE 方法

put 相对应,两者都不具备验证机制

  • OPTIONS 询问支持的方法: 用来查询针对请求 URI 指定的资源支持的方法(了解即可)
  • TRACE 追踪路径:Web 服务器端将之前的请求通信返回给客户端的方法。 但 TRACE 方法本来就不怎么常用,再加上它容易引发 XST攻击,通常就更不会用到了(了解即可)
  • CONNECT 要求用隧道协议连接代理: 要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信。 主要使用 SSL(Secure Sockets Layer,安全套接层)和 TLS(Transport Layer Security,传输层安全)协议把通信内容加密后经网络隧道传输。

2.2 持久连接节省通信量

2.2.1 持久链接

持久连接的特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态

持久连接的好处:

  • 减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载

感觉有点类似于连接池的作用

  • 减少开销的那部分时间,使 HTTP 请求和响应能够更早地结束,这样 Web 页面的显示速度也就相应提高了

2.2.2 管线化

管线化技术出现后,不用等待响应亦可直接发送下一个请求

这样就能够做到同时并行发送多个请求,而不需要一个接一个地等待响应了

用持久连接可以让请求更快结束。而管线化技术则比持久连接还要快。请求数越多,时间差就越明显。

状态管理其实还有很多种,比如 Session ,token ,这里仅介绍 cookie

HTTP 是无状态协议,它不对之前发生过的请求和响应的状态进行管理。

Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去

三、HTTP 报文内的 HTTP 信息

3.1 压缩传输的内容编码

内容编码指明应用在实体内容上的编码格式,并保持实体信息原样压缩

常用的内容编码有:

  • gzip
  • compress
  • deflate
  • identity

四、返回结果的 HTTP 状态码

4.1 状态码告知从服务器端返回的请求结果

数字中的第一位指定了响应类别,后两位无分类

类别 原因短语
1XX Informational 接收的请求正在处理
2XX Success 请求正常处理完毕
3XX Redirection 需要进行附加操作以完成请求
4XX Client Error 客户端无法处理请求
5XX Server Error 服务器处理请求出错

4.2 2xx 成功

2xx 成功

4.3 3xx 重定向

4.4 4XX 客户端错误

image-20200711224935405

PS:注意区分 403 和 404,一个是被拒绝(一般是权限问题),另一个是无法找到

4.5 5XX 服务器错误

五、Web 服务器

5.1 用单台虚拟主机实现多个域名

HTTP1.1 规范允许一个服务器搭建多个 Web 站点,这是虚拟主机功能。

Q1:为啥 Host 首部内完整指定主机名或域名URI

因为虚拟主机可以寄存多个不同主机名和域名Web 网站

5.2 通信数据转发程序

这些应用程序和服务器可以将请求转发给通信线路上的下一站服务器,并且能接收从那台服务器发送的响应再转发给客户端。

  1. 代理:接收客户端发送的请求后转发给其他服务器;代理不改变请求 URI,会直接发送给前方持有资源的目标服务器。
  • 缓存代理:预先将资源缓存保存在代理服务器上,当代理再次接收到对相同资源的请求时,就可以直接将之前缓存的资源作为响应返回
  • 透明代理:转发请求或响应时,不对报文做任何加工被称为透明代理,对报文内容进行加工的称为非透明代理。

image-20200712195432972

2.网关:转发其他服务器通信数据的服务器,接收从客户端发送来的请求时,它就像自己拥有资源的源服务器一样对请求进行处理。

image-20200712195459045

3.隧道: 按要求建立起一条与其他服务器的通信线路,届时使用 SSL 等加密手段进行通信,在通信双方断开连接时结束。隧道的目的是确保客户端能与服务器进行安全的通信。

5.3 保存资源的缓存

客户端的缓存: 浏览器缓存如果有效,不必再向服务器请求,而直接从本地读取。当判定缓存过期后,会向源服务器确认资源的有效性。若判断浏览器缓存失效,浏览器会再次请求新资源。

image-20200712172523006

六、HTTP 首部

HTTP 协议的请求和响应报文中必定包含 HTTP 首部,请求报文和响应报文结构如下

image-20200713143253306

image-20200713143234364

6.1 HTTP 首部字段

HTTP 首部字段将定义成缓存代理非缓存代理的行为,分成 2 种类型。

  1. 端到端首部: 分在此类别中的首部会转发给请求 / 响应对应的最终接收目标,且必须保存在由缓存生成的响应中,另外规定它必须被转发
  2. 逐跳首部: 分在此类别中的首部只对单次转发有效,会因通过缓存或代理而不再转发。HTTP1.1 和之后版本中,如果要使用 hop-by-hop 首部,需提供 Connection 首部字段。

6.1.1 通用首部字段

请求报文和响应报文两方都会使用的首部。

首部字段名 说明
Cache-Control 控制缓存的行为
Connection 逐跳首部、连接的管理
Date 创建报文的日期时间
Pragma 报文指令
Trailer 报文末端的首部一览
Transfer-Encoding 指定报文主体的传输编码方式
Upgrade 升级为其他协议
Via 代理服务器的相关信息
Warning 错误通知

6.1.2 请求首部字段

从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。

首部字段名 说明
Accept 用户代理可处理的媒体类型
Accept-Charset 优先的字符集
Accept-Encoding 优先的内容编码
Accept-Language 优先的语言(自然语言)
Authorization Web认证信息
Expect 期待服务器的特定行为
From 用户的电子邮箱地址
Host 请求资源所在服务器
If-Match 比较实体标记(ETag)
If-Modified-Since 比较资源的更新时间
If-None-Match 比较实体标记(与 If-Match 相反)
If-Range 资源未更新时发送实体 Byte 的范围请求
If-Unmodified-Since 比较资源的更新时间(与If-Modified-Since相反)
Max-Forwards 最大传输逐跳数
Proxy-Authorization 代理服务器要求客户端的认证信息
Range 实体的字节范围请求
Referer 对请求中 URI 的原始获取方
TE 传输编码的优先级
User-Agent HTTP 客户端程序的信息

6.1.3 响应首部字段

从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。

首部字段名 说明
Accept-Ranges 是否接受字节范围请求
Age 推算资源创建经过时间
ETag 资源的匹配信息
Location 令客户端重定向至指定URI
Proxy-Authenticate 代理服务器对客户端的认证信息
Retry-After 对再次发起请求的时机要求
Server HTTP服务器的安装信息
Vary 代理服务器缓存的管理信息
WWW-Authenticate 服务器对客户端的认证信息

6.1.4 实体首部字段

针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。

首部字段名 说明
Allow 资源可支持的HTTP方法
Content-Encoding 实体主体适用的编码方式
Content-Language 实体主体的自然语言
Content-Length 实体主体的大小(单位:字节)
Content-Location 替代对应资源的URI
Content-MD5 实体主体的报文摘要
Content-Range 实体主体的位置范围
Content-Type 实体主体的媒体类型
Expires 实体主体过期的日期时间
Last-Modified 资源的最后修改日期时间

6.2 HTTP1.1 通用首部字段

通用首部字段是指请求报文和响应报文都会使用的首部。

6.2.1 Cache-Control

  1. no-cache: 防止从缓存中返回过期的资源。客户端请求如果包含 no-cache,表示客户端将不会接收缓存过的响应,缓存服务器必须把客户端请求转发给源服务器。服务器响应中包含 no-cache,那么缓存服务器不能对资源进行缓存,源服务器以后也将不再对缓存服务器请求中提出的资源有效性进行确认,且禁止其对响应资源进行缓存操作。
  2. no-store: 缓存不能在本地存储请求或响应的任一部分。

从字面意思上很容易把 no-cache 误解成为不缓存,但 no-cache 代表不缓存过期的资源,缓存会向源服务器进行有效期确认后处理资源,no-store 才是真正地不进行缓存

6.2.2 Connection

1.控制不再转发给代理的首部字段: 在客户端发送请求和服务器返回响应内,使用 Connection 首部字段,可控制不再转发给代理的首部字段(即 Hop-by-hop 逐跳首部)。

2.管理持久连接: HTTP1.1 默认持久连接,客户端会在持久连接上连续发送请求。服务器端想断开连接时,则设置 Connection 首部字段为 CloseHTTP1.1 之前默认都是非持久连接。为此,如果想在旧版本 HTTP 协议上持续连接,则需设置 Connection 首部字段为 Keep-Alive

6.2.3 Date

表明创建 HTTP 报文的日期和时间。

6.2.4 Upgrade

用于检测 HTTP 协议及其他协议是否可使用更高的版本进行通信,其参数值可以用来指定一个完全不同的通信协议。

6.3 请求首部字段

从客户端往服务器端发送请求报文中所使用的字段,用于补充请求的附加信息、客户端信息、对响应内容相关的优先级等内容。

6.3.1 Accept

通知服务器,用户代理能够处理的媒体类型媒体类型的相对优先级。可使用 type/subtype 这种形式,一次指定多种媒体类型。

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

6.3.2 Host

告知服务器,请求的资源所处的互联网主机名和端口号。Host 首部字段在 HTTP1.1 规范内是唯一一个必须被包含在请求内的首部字段。

6.3.3 If-Match

形如 If-xxx 这种,都可称为条件请求。服务器接收到后,只有判断指定条件为真时,才会执行请求

6.3.4 If-None-Match

If-Match 相反

6.3.5 If-Modified-Since

如果在 If-Modified-Since 字段指定的日期时间后资源发生了更新,服务器会接受请求。

6.3.6 If-Unmodified-Since

If-Modified-Since 的作用相反

6.3.7 If-Range

字段如果跟 ETag 值或更新的日期时间一致,那么就作为范围请求处理。反之,则返回全体资源。

6.4 响应首部字段

由服务器端向客户端返回响应报文中所使用的字段,用于补充响应的附加信息服务器信息,以及对客户端的附加要求等信息。

6.4.1 ETag

实体标识,将资源以字符串形式做唯一性标识的方式。服务器会为每份资源分配对应的 ETag 值。当资源更新时,ETag 值也需要更新。

若在下载过程中出现连接中断、再连接的情况,都会依照 ETag 值来指定资源。

6.5 实体首部字段

包含在请求报文和响应报文中的实体部分所使用的首部,用于补充内容的更新时间等与实体相关的信息。

6.5.1 Allow

通知客户端能够支持的所有 HTTP 方法。当服务器接收到不支持的 HTTP 方法时,会以状态码 405 Method Not Allowed 作为响应返回。与此同时,还会把所有能支持的 HTTP 方法写入首部字段 Allow 后返回。

6.5.2 Content-Encoding

告知客户端服务器对实体的主体部分选用的内容编码方式。内容编码是指在不丢失实体信息的前提下所进行的压缩。

主要有:gzipcompressdeflateidentity

6.5.3 Content-Type

说明了实体主体内对象的媒体类型,用 type/subtype 形式赋值。

6.5.4 Expires

Expires 会将资源失效的日期告知客户端。缓存服务器在收到有 Expires 的响应后,会以缓存来应答请求,在 Expires 字段值指定的时间之前,响应的副本会一直被保存。当超过指定的时间后,缓存服务器在请求发送过来时,会转向源服务器请求资源。

6.5.5 Last-Modified

包含源头服务器认定的资源做出修改的日期及时间

首部字段名 说明 首部类型
Set-Cookie 开始状态管理所使用的Cookie信息 响应首部字段
Cookie 服务器接收到的Cookie信息 请求首部字段

6.7 其他首部字段

6.7.1 X-XSS-Protection

是针对跨站脚本攻击(XSS)的一种对策,用于控制浏览器 XSS 防护机制的开关,可指定的字段值如下

  • 0:将 XSS 过滤设置成无效状态
  • 1:将 XSS 过滤设置成有效状态

七、 HTTPS

HTTP 协议中有可能存在信息窃听或身份伪装等安全问题,怎么解决呢?HTTPS 了解一下

7.1 HTTP 的缺点是啥?

  • 通信使用明文(不加密),内容可能会被窃听
  • 不验证通信方的身份,因此有可能遭遇伪装
  • 无法证明报文的完整性,所以有可能已遭篡改

7.2 HTTPS 是啥 ?

简单来说,就是:HTTP+ 加密 + 认证 + 完整性保护

把添加了加密及认证机制的 HTTP 称为 HTTPS

HTTPS 并非是应用层的一种新协议,只是 HTTP 通信接口部分用 SSL(Secure Socket Layer)和 TLS(Transport Layer Security)协议代替而已。

image-20200714132749462

HTTPS 采用共享密钥加密(对称加密)和公开密钥加密(非对称加密)两者并用的混合加密机制。若密钥能够实现安全交换,那么有可能会考虑仅使用公开密钥加密来通信。但是公开密钥加密与共享密钥加密相比,其处理速度要慢。

所以取长补短,在交换密钥环节使用公开密钥加密方式,之后的建立通信交换报文阶段则使用共享密钥加密方式。

数字证书认证机构(CA,Certificate Authority)和其相关机关颁发的公开密钥证书就是认证的可以信赖的公开密钥,服务器会将这份由数字证书认证机构颁发的公钥证书发送给客户端,以进行公开密钥加密方式通信。公钥证书也可叫做数字证书或直接称为证书。

image-20200714133015217

7.2.1 SSL 速度慢吗

当使用 SSL 时,它的处理速度会变慢。它慢分两种:

  • 一种是指通信慢

还必须进行 SSL 通信,所以慢

  • 另一种是指由于大量消耗 CPU 及内存等资源,导致处理速度变慢

服务器和客户端都需要进行加解密处理

针对速度变慢这一问题,并没有根本性的解决方案,一般会使用 SSL 加速器这种(专用服务器)硬件。

7.2.2 为啥没使用 HTTPS ?

  • 加密通信会消耗更多的 CPU 及内存资源
  • 如果是非敏感信息则使用 HTTP 通信,只有在包含个人信息等敏感数据时,才利用 HTTPS 加密通信。可以仅在那些需要信息隐藏时才加密,以节约资源
  • 节约购买证书的开销

八、确认访问用户身份的认证

一些页面只想让特定的人浏览,这就引入了认证功能。

HTTP1.1 常用的认证方式:

  1. BASIC 认证(基本认证)
  2. DIGEST 认证(摘要认证)
  3. SSL 客户端认证
  4. FormBase 认证(基于表单认证)

九、基于 HTTP 的功能追加协议

9.1 WebSocket

连接的发起方仍是客户端,一旦确立 WebSocket 通信连接,服务器与客户端任意一方都可向对方发送报文

  1. 推送功能: 支持由服务器向客户端推送数据的推送功能。这样,服务器可直接发送数据,而不必等待客户端的请求。
  2. 减少通信量:HTTP 相比,不但每次连接时的开销减少,且由于首部信息很小,通信量也减少了。

通信的建立:

1.首先使用 HTTPUpgrade 首部字段,告知服务器通信协议发生改变,进行握手。

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Origin: http://example.com
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13

Sec-WebSocket-Key 字段内记录着握手过程中必不可少的键值。Sec-WebSocket-Protocol 字段内记录使用的子协议。

2.之前的请求将会被返回 101 Switching Protocols 响应

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protocol: chat

成功握手建立 WebSocket 连接之后,通信时不再使用 HTTP 的数据帧,而采用 WebSocket 独立的数据帧

9.2 HTTP/2.0

HTTP/2.0 的目标是改善用户在使用 Web 时的速度体验。特点:

  1. HTTP/2.0 采用二进制格式而非文本格式(二进制分帧
  2. HTTP/2.0 是完全多路复用的,而非有序并阻塞的——只需一个连接即可实现并行

问题又来了,HTTP 1.1 不是通过管线化可以实现并发吗?为啥要用2.0?

答案:

虽然 HTTP/1.1 管线化可以支持请求并发,但是浏览器很难实现chromefirefox 等都禁用了管线化。所以1.1版本请求并发依赖于多个 TCP 连接,建立 TCP 连接成本很高,还会存在慢启动的问题。

  1. 使用报头压缩,HTTP/2.0 降低了开销(头部压缩
  2. HTTP/2.0 让服务器可以将响应主动“推送”到客户端缓存中

如果文章对您有一点帮助的话,希望您能点一下赞,您的点赞,是我前进的动力

本文参考链接:


 上一篇
面试锦囊 | HTTP 面试门路 面试锦囊 | HTTP 面试门路
本文将通过几个问题,以面试官提问的方式出发,思考问题,锻炼思维的深度和广度,你想要的有可能就在这里!
下一篇 
午间邂逅 | post 和 get 的兄弟情深 午间邂逅 | post 和 get 的兄弟情深
面试官:『请你说下 post 和 get 的区别!』看到这里,很多人禁不住内心的喜悦,嘴角微微上扬,然后强装镇定,拿出背好的拿手绝活,轻轻松松给出了「标准答案」
  目录