iOS开发进阶:HTTP知识点梳理

本文整理 《图解HTTP》中的知识点,方便查阅。

网络基础

基本术语

  • HTTP : 超文本传输协议。
  • DNS : 域名系统。
  • FTP : 文件传输协议。
  • TCP : 传输控制协议
  • UDP : 用户数据报协议。
  • TCP/IP协议族 : 通常使用的网络是在 TCP/IP 协议族的基础上运行的。HTTP 属于它内部的一个子集。
  • URI 全称统一资源标识符。
  • URL 全称统一资源定位符。

TCP/IP

TCP/IP协议族分为四层:应用层、传输层、网络层、数据链路层。

应用层

决定向用户提供应用服务是通信的活动。TCP/IP 中预存了各类通用的应用服务。例如: FTP、HTTP、DNS等。

传输层

为应用层提供处于网络连接中的两台计算机之间的数据传输。 例如:TCP 和 UDP。

网络层

网络层用来处理网络上流动的数据包。数据包是网络传输的最小单位。

数据链路层

用于处理连接网络的硬件部分。

IP、TCP 和 DNS

IP

IP 协议位于网络层,TCP/IP 协议族中的指的是 IP 协议。它的作用是把各种数据包传递给对方,还有两个重要条件 IP 地址和 MAC 地址。其中,IP地址 指明节点被分配的地址。MAC地址 是指网卡所属的固定地址。

TCP

TCP 位于传输层,提供可靠的字节流服务。其中,字节流是为了传输方便将大块数据分割成报文段为单位的数据包进行管理。可靠传输服务是指把数据准确可靠地传输给对方。

为了准确无误地传输数据,TCP协议 采用三次握手策略。流程如下:

发送端先发送一个带 SYN 标志的数据包给对方。接收端收到后,返回一个带 SYN/ACK 标志的数据包以示传达确认。最后发送端在回传一个带 ACK 标志的数据包,至此握手结束。

DNS

DNS 服务是和 HTTP 协议一样位于应用层的协议。它提供域名到 IP地址 之间的解析服务。

什么是 HTTP 协议 ?

HTTP/1.1 为例,学习 HTTP 协议结构。

HTTP 是一种无状态的协议。不会对请求和响应之前的通讯状态进行保存。为了保存状态引入了 Cookie 技术。

Cookie 通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。根据服务器发送响应报文内 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。客户端在下次发送请求时带上 Cookie 值,这样服务器通过 Cookie 值就能知道是谁发送的请求。

HTTP 使用 URL 定位网络资源。

HTTP 方法

  • GET: 获取资源。
  • POST: 传输实体主体。
  • PUT: 传输文件。
  • HEAD: 获取报文首部。
  • DELETE: 删除文件。
  • OPTIONS: 询问支持的方法。

持久连接 & 管线化

在初始版本中,每进行一次HTTP通信就要断开一次TCP连接。如果多次请求时,需要重复TCP建立和断开,增加通信量的开销。

为了解决这个问题,HTTP/1.1 引入了持久连接,也称为 HTTP keep-alive。持久连接的特点是只要任意一端没有确切提出断开连接,则保持连接状态。持久连接有效减少 TCP 连接的重复建立和断开造成的额外开销,减轻服务器负载。

持久连接使得多数请求以管线化方式发送数据成为可能。同时并行发送多个请求,而不需要一个个等待响应。

什么是 HTTP 报文?

HTTP 报文类型分为 :请求报文响应报文

HTTP 报文 结构大致分为报文首部和报文主体两块。两者有空行来划分,通常并不一定存在报文主体。

报文首部包含:请求行、请求首部、状态行、响应首部、通用首部、实体首部等。

  • 请求行: 包含请求的方法,请求 URI 和 HTTP 版本。例如,GET / HTTP/1.1
  • 状态行:包含表明响应结果的状态码,原因短语和HTTP版本。例如:HTTP/1.1 200 OK
  • 首部字段:包含表示请求和响应的各种条件和属性的各类首部。通常分为四类:通用首部、请求首部、响应首部和实体首部。

以下是访问 www.baidu.com 时,请求和响应报文内容。

请求报文

1
2
3
4
5
6
7
8
9
10
GET / HTTP/1.1  // 请求行
Host: www.baidu.com
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cookie: PSTM=1518691422; BAIDUID=EF4A64062C428815273427B3F961C974:FG=1; BDUSS=pTVjIxcjRUWmJTMXoxQ3FmLW5DbW56cDR6WXphZWM0cmZOclltYVJ4cnREcmRiQVFBQUFBJCQAAAAAAAAAAAEAAABng3or18-15zg1MTM3NDY5NQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAO2Bj1vtgY9ba1; BIDUPSID=70BAE3F1F24CEA12C374D699B2F27CB5; BD_UPN=123253; MCITY=-236%3A; pgv_pvi=3700291584; BDRCVFR[r3VqGGrxDQ3]=mk3SLVN4HKm; BD_HOME=1; H_PS_PSSID=1445_21118_28558; sug=3; sugstore=0; ORIGIN=0; bdime=0

响应报文首部

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
HTTP/1.1 200 OK //状态行
Bdpagetype: 2
Bdqid: 0x9ce7a85b000123dc
Cache-Control: private
Connection: Keep-Alive
Content-Encoding: gzip
Content-Type: text/html;charset=utf-8
Date: Thu, 28 Feb 2019 05:03:42 GMT
Expires: Thu, 28 Feb 2019 05:03:42 GMT
Server: BWS/1.1
Set-Cookie: BDSVRTM=401; path=/
Set-Cookie: BD_HOME=1; path=/
Set-Cookie: H_PS_PSSID=1445_21118_28558; path=/; domain=.baidu.com
Strict-Transport-Security: max-age=172800
X-Ua-Compatible: IE=Edge,chrome=1
Transfer-Encoding: chunked

HTTP 报文首部

通用报文首部字段

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

通用首部字段《图解HTTP》

Cache-Control

操作缓存的工作机制。常见指令如:

缓存请求指令
image

缓存响应指令
image

Connection

Connection首部字段具备两个作用:控制不再转发给代理的首部字段,管理持久连接。 Keep-Alive 表示持久连接。

Date

Date : 表示报文的创建日期和时间。

请求首部字段

请求首部字段是客户端向服务器端发送请求时使用的字段,用于补充请求的附加信息、客户信息、对响应内容相关的优先级等。

image

响应首部字段

响应首部字段是服务器返回报文时使用的字段,用于补充响应的附加信息、服务器信息、以及对客户端的附加要求等。

image

实体首部字段

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

image

常见的 HTTP 状态码

状态码用于描述返回的请求结果。

通常 3 位数字组成,第一位指定响应类别,后两位没有分类。响应类别分为 5 类:

类别 说明
1xx 信息性状态码 接收的请求正在处理
2xx 成功 请求正常处理完毕
3xx 重定向 需要添加附加操作以完成请求
4xx 客户端错误 服务器无法处理的请求
5xx 服务器错误 服务器处理请求出错

2xx 成功

  • 200 : 表示客户端发来的请求被服务器正常处理。
  • 204 : 表示客户端发送的请求被服务器正常处理,但没有资源可返回。
  • 206 : 表示客户端进行范围请求,服务器成功处理请求。响应报文中包含 Content-Range 指定范围的实体内容。

3xx 重定向

  • 301 : 永久性重定向。表示请求资源被重新分配了 URI ,之后资源使用现在的 URL
  • 302 : 临时性重定向。表示请求资源被重新分配了 URI,且只有本次使用新的 URI 访问。
  • 303 : 表示由于请求的资源存在着另一个 URI,应使用 GET 方法定向获取请求的资源。

4xx 客户端错误

  • 400 : 表示请求报文中存在语法错误。
  • 401 : 表示请求需要有通过 HTTP 认证的认证信息。
  • 403 : 表示请求资源的访问被服务器拒绝了。
  • 404 : 表示服务器无法找到请求的资源。

5xx 服务器错误

  • 500 : 表明服务器端在执行请求时发生了错误。
  • 503 : 表示服务器正在超负载或者正在进行停机维护,无法处理请求。

什么是 HTTPS ?

HTTP 主要缺点:

  • 通信使用明文,内容可能被窃听。
  • 不验证通信仿的身份,因此可能遭遇伪装。
  • 无法保证报文的完整性,所以可能遭到篡改。

HTTPS = HTTP + 加密 + 认证 + 完整性保护,所以把添加了加密及认证机制的 HTTP 称为 HTTPS

HTTPS并不是应用层的新协议,只是身披SSL 外壳的 HTTP协议。通常情况下,HTTP直接和TCP通信。当使用SSL时,则先和 SSL通信再由它同TCP通信。

SSL是独立于HTTP的协议,在很多方面都有使用。它采用一种叫做公开秘钥加密的加密处理方法。

加密

  • 共享密钥加密(对称密钥加密): 加密和解密同用一个密钥的方式。
  • 公开密钥加密(非对称加密):这种方式存在两把密钥:私有密钥和公开密钥。

HTTPS采用公开密钥加密和共享密钥混合的加密机制。由于公开密钥加密机制比较复杂,因此在通信时使用处理效率较低。HTTPS先采用公开密钥加密将共享密钥发送给对方。然后使用共享加密方式通信。

公开密钥存在一个问题:无法证明密钥本身是否是真实的。为了解决这个问题,使用数字证书认证(CA)和相关机关颁发的公开密钥证书。

image

HTTPS 安全通信流程

  1. 客户端发送 Client Hello报文开始 SSL 通信。
  2. 服务器端以 Server Hello报文作为应答。
  3. 之后服务器发送 Certificate 报文,包含公开密钥证书。
  4. 服务器发送 Server Hello Done 通知客户端,最初阶段 SSL 握手协商结束。
  5. SSL握手结束后,客户端以 Client Key Exchange报文作为回应。报文中包含通信加密中使用的随机密码串。密码串已被第三步中的公开密钥进行加密。
  6. 客户端发送 Change Cipher spec 报文,告诉服务器,接下来使用上一步发送的随机密码串进行加密。
  7. 客户端发送 Finished 报文。报文包含连接至今全部报文的整体校验值。
  8. 服务器返回 Change Cipher Spec报文。
  9. 服务器发送 Finished 报文。
  10. SSL连接建立完成。开始发送 HTTP 请求。

HTTP 缓存机制

缓存相关的首部字段

  • Expires : 实体首部字段,资源实体的过期时间。
  • Cache-Control: 通用首部字段,缓存控制字段,精确控制缓存策略。
  • If-Modified-Since: 请求首部字段,资源最近修改时间,由浏览器告诉服务器。与Last-Modified配对使用。
  • Last-Modified: 响应首部字段,资源最近修改时间,由服务器告诉浏览器。
  • Etag: 响应首部字段。资源标识,由服务器告诉浏览器。与 If-None-Match配对使用。
  • If-None-Match: 请求首部字段。缓存资源标识,由浏览器告诉服务器。

缓存机制

过期时间

服务器和浏览器约定文件过期时间,用 Expires 字段控制,时间是 GMT 格式的标准时间。

浏览器请求数据后将文件缓存在本地,下次请求时查看是否过期,未过期使用本地缓存的,过期则重新请求。

缺点:过期后,服务器不论数据是否变化,都会重新读取文件,返回给浏览器。

过期时间 + 上次修改时间

为了解决上面的问题,指定一种方案,服务器每次返回数据时,告诉服务器文件在服务器上最近修改时间 Last-Modified 和 过期时间 Expires

当服务器返回数据时,携带上次修改时间(Last-Modified)和缓存过期时间 Expires。当缓存过期后,浏览器带上 If-Modified-Since (等于 Last-Modified)请求服务器。服务器比较 If-Modified-Since和文件修改时间。如相同告诉服务器使用本地缓存(304)。否则返回新的数据以及 Last-ModifiedExpires

缺点:过期时间控制不稳定,浏览器可以随意修改时间。Last-Modified只能精确到秒。例如,一个文件在一秒内经常变动,浏览器无法感知。

相对时间控制 Cache-Control

引入新的缓存方案,服务器不仅告诉浏览器 Expires 同时告诉一个相对时间 Cache-Control: max-age=10,意思10秒内缓存有效。

浏览器会先检查 Cache-Control,如果有忽略 Expires以它为准。

文件内容对比 Etag

为了解决文件修改时间只能精确到秒的问题,引入 Etag。文件内容改变 Etag才会改变,可以理解为文件的唯一 ID。同时引入对应的 If-None-Match(等于上次返回的 Etag)。浏览器每次请求都带上 If-None-Match字段。

浏览器请求数据,服务器会返回过期时间Expires、相对时间 Cache-Control: max-age=10、上次修改时间 Last-ModifiedEtag。在10秒内再次请求文件会直接使用本地缓存数据。如11秒再次请求服务器,会带上 If-Modified-SinceIf-None-Match。服务器接收到发现有 If-None-Match则会与 Etag值比较,忽略 If-Modified-Since。如果文件内容没改变则告诉浏览器使用本地缓存 (304)。

缓存部分参考文章: 《面试精选之http缓存》

小结

以上是阅读 《图解HTTP》整理全部的知识点。