HTTP
# 什么是 HTTP
# 概念
HTTP(HyperText Transfer Protocol)即超文本运输协议,是实现网络通信的一种规范。常被用于在web浏览器和网站服务器之间传递信息,以明文传递内容,不进行任何加密。默认端口号为 80。
# HTTP 特点
- 支持客户端/服务器模式
- 简单快速
- 灵活:http 允许传输任何类型的数据类型,用 content-type 标记正在传输的类型。
- 无连接:每次连接只处理一个请求,请求完成后即断开 tcp 连接。每一个请求都要重新建立 TCP 连接(1.0 版本)
- 无状态:http 协议无法根据上一次连接的状态进行本次的请求处理
# HTTP 1.0/1.1/2.0 的区别
# HTTP 1.0
浏览器只和服务器保持短暂的连接,每次发起请求时都需要和服务器建立 TCP 连接,服务器完成请求处理后立即断开连接。
要建立起长连接,需要设置一个非标准的 Connection 字段:Connection: keep-alive
# HTTP 1.1
- HTTP 1.1 支持长连接且默认开启,从而一个 TCP 连接可以发起多个 HTTP 请求,减少了建立和关闭连接的消耗和延迟。
- 持续化连接使多数请求以管线化方式发送成为可能。之前发送请求需要等待并得到响应后,才可以发送下一个请求,而使用管道化技术后可以不用等待响应而直接发送下一个请求。
- 新增了请求方式:
OPTION
、TRACE
、CONNECT
- 增加了更多的请求头和响应头来完善功能:
- 引入了更多的缓存控制策略,如
If-Unmodified-Since
,If-Match
,If-None-Match
等缓存头来控制缓存策略 - 引入
range
,允许值请求资源某个部分 - 引入
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,代表资源没更新。
缺点:
- 资源只要编辑了,不管内容是否有变,修改时间都会更新
- 时间的精确度只能到秒,即一秒内的修改是监测不到更新的,仍会使用旧的缓存
- 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 请求获取最新的资源
# 总结
- 对于强缓存,
Cache-Control
优先级高于Expires
- 对于协商缓存,
Etag
优先级高于Last-Modified
- 强缓存优先级高于协商缓存,若强缓存生效则直接使用强缓存,否则进行协商缓存
# HTTP 事务
概念:
一个完整的请求+响应称之为HTTP事务。HTTP 事务是一个整体,在这个过程中,信息要么一次性交换完,要么完全不交换,而不能被分割
组成:
- TCP 连接
- HTTP 请求
- HTTP 响应
- 断开连接。也可以保持连接不断开,给下一个HTTP 事务使用