HTTP

2022/9/3

# 什么是 HTTP

# 概念

HTTP(HyperText Transfer Protocol)即超文本运输协议,是实现网络通信的一种规范。常被用于在web浏览器和网站服务器之间传递信息,以明文传递内容,不进行任何加密。默认端口号为 80。

# HTTP 特点

  1. 支持客户端/服务器模式
  2. 简单快速
  3. 灵活:http 允许传输任何类型的数据类型,用 content-type 标记正在传输的类型。
  4. 无连接:每次连接只处理一个请求,请求完成后即断开 tcp 连接。每一个请求都要重新建立 TCP 连接(1.0 版本
  5. 无状态:http 协议无法根据上一次连接的状态进行本次的请求处理

# HTTP 1.0/1.1/2.0 的区别

# HTTP 1.0

浏览器只和服务器保持短暂的连接,每次发起请求时都需要和服务器建立 TCP 连接,服务器完成请求处理后立即断开连接。
要建立起长连接,需要设置一个非标准的 Connection 字段:Connection: keep-alive

# HTTP 1.1

  • HTTP 1.1 支持长连接且默认开启,从而一个 TCP 连接可以发起多个 HTTP 请求,减少了建立和关闭连接的消耗和延迟。
  • 持续化连接使多数请求以管线化方式发送成为可能。之前发送请求需要等待并得到响应后,才可以发送下一个请求,而使用管道化技术后可以不用等待响应而直接发送下一个请求。
  • 新增了请求方式:OPTIONTRACECONNECT
  • 增加了更多的请求头和响应头来完善功能:
    1. 引入了更多的缓存控制策略,如 If-Unmodified-Since, If-Match, If-None-Match等缓存头来控制缓存策略
    2. 引入 range,允许值请求资源某个部分
    3. 引入 host,实现了在一台WEB服务器上可以在同一个IP地址和端口号上使用不同的主机名来创建多个虚拟WEB站点

# HTTP 2.0

多路复用
在一次 TCP 连接中,客户端和服务器都可以并发发送多个请求或回应,而不用按顺序一一对应

二进制分帧
HTTP 2.0 采用二进制格式传输数据,而非之前的文本格式,解析速度更快

首部压缩
HTTP 2.0 在客户端和服务器端使用“首部表”来跟踪和存储之前发送的键值对,对于相同的数据,不再通过每次请求和响应发送。
例如有两个请求,请求一发送了所有的头部信息,而请求二只需要发送差异部分的信息即可

服务器推送
HTTP 2.0 允许服务端推送数据给客户端。
当客户端请求一个页面时,服务器可顺带推送用户需要的其他资源,减少客户端发起请求的次数

# HTTP 缓存控制

# 概念

浏览器缓存是浏览器在本地磁盘对用户最近请求的文档进行缓存,当用户再次发起对该文档资源的请求时,浏览器可以从磁盘直接读取对应资源。缓存主要分为强缓存协商缓存

# 强缓存

1. 特点: 直接从本地副本比较读取,而不需要请求服务器,命中时返回的状态码是 200
2. 控制的字段

  • Expires
    Expires 是 HTTP/1.0 中定义的缓存字段,其值是一个 GMT 格式的时间。当我们发起一个请求,服务器返回时,可以在回复的头部(Response Headers)增加 Expires 字段表明资源的过期时间。当客户端再次发起同一请求时,会将客户端时间与该时间进行比较,小于则证明缓存未过期,直接从磁盘读取。
expires: Sun, 04 Sep 2022 10:30:48 GMT

缺点: 客户端时间和服务器时间不一定统一,并且用户可以更改自己客户端的时间

  • Cache-Control Cache-Control 是 HTTP/1.1 进行缓存控制的字段,其值有:
    • max-age=xxx:表示缓存离过期还有多少秒
    • public:可以被所有用户缓存
    • private:只能被客户端缓存
    • no-cache:不使用强缓存,但可以使用协商缓存
    • no-store:所有内容都不会被缓存,既不能使用强缓存,也不使用协商缓存,即每个请求都需要完整下载资源

# 协商缓存

  • Last-Modified / If-Modified-Since
    Last-Modified 是第一次发起请求时,返回该资源在服务器最后一次修改的时间
    再次发起同一请求时,会带上 If-Modified-Since 字段,其值等于上次返回的 Last-Modified。服务器通过对比该字段的值和该资源在服务器最后修改的时间,如果修改时间晚于 If-Modified-Since,返回200;否则命中缓存,返回304,代表资源没更新。

缺点:

  1. 资源只要编辑了,不管内容是否有变,修改时间都会更新
  2. 时间的精确度只能到秒,即一秒内的修改是监测不到更新的,仍会使用旧的缓存
  • Etag / If-None-Match
    Etag 是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成)
    If-None-Match 是客户端再次发起请求时,携带上次请求返回的唯一标识Etag值,服务端收到该请求后,发现该请求含有 If-None-Match,则会根据If-None-Match的字段值与该资源在服务器的Etag值做对比,一致则返回304,代表资源无更新,继续使用缓存文件,否则重新返回资源,状态码为200

# 应用场景

  • 对于 HTML 这种包含了其他文件的主要文件,为了确保当其内容修改时页面能够及时地更新,一般直接使用协商缓存,即为 cache-control 增加 no-cache 属性值
  • 对于图片文件这种,一般修改都是直接改变链接,所以可以直接采取强缓存,同时由于图片的数量和大小一般较大,可能会占用较多的客户端缓存,所以也不宜设置时间过长,可设置为 max-age = 86400
  • 对于样式、js脚本等文本文件,如果内容不会定期更新,可以考虑在命名时加上版本号,然后使用强缓存并可以设置一个较长的时间。这样既能使用强缓存提高重用效率,又因为修改后版本号不同,即文件 URL 改变了,不需要再进行缓存的判断,而可以直接发起 http 请求获取最新的资源

# 总结

  1. 对于强缓存,Cache-Control 优先级高于 Expires
  2. 对于协商缓存,Etag 优先级高于 Last-Modified
  3. 强缓存优先级高于协商缓存,若强缓存生效则直接使用强缓存,否则进行协商缓存

# HTTP 事务

概念:
一个完整的请求+响应称之为HTTP事务。HTTP 事务是一个整体,在这个过程中,信息要么一次性交换完,要么完全不交换,而不能被分割

组成:

  1. TCP 连接
  2. HTTP 请求
  3. HTTP 响应
  4. 断开连接。也可以保持连接不断开,给下一个HTTP 事务使用