持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第16天,点击查看活动详情
- Hello,这里是mouche,当然你也可以叫我某车,反正大家都爱这么叫😁
- 来点前置知识
- HTTP/1.0正式作为标准公布是在1996年5月
- HTTP/1.1正式发布是在1997年1月
- HTTP/2 正式发布是在2014年12月
一、连接相关
- 在这之前我们可以先了解一下浏览器请求一个万维网文档到收到整个文档所需的时间
- 我们都知道发送请求前需要建立起TCP连接,在TCP连接的第三次握手的是可以携带数据的
因为第三次握手此时已经能够知道服务器的接收和发送功能正常,同时在客户端发起第三次握手后已经进入了
ESTAB-LISHED状态,也能正常接收服务器响应的数据
- 如下图所示所需的时间为两次往返时间
RTT(一个用于TCP连接,一个用于发送和接收数据)+ 文件传输的时间 - 那么
HTTP/1.0是非持续连接的,默认是每一次请求都需要去进行上述的过程,也就是每一次请求都要去建立TCP连接,服务器响应后就立马断开连接,在这种情况下无疑对服务器的负担很重
不过每个浏览器能够打开5-10个并行的TCP连接,在一定程度上也缩短了时间,注意: 这里的并行要和下面HTTP2.0的并行区分一下
- 于是
HTTP/1.1就站出来了,它是默认使用了持续连接,也就是说,我只要建立一次TCP连接,后续就可以直接在这条连接上传送后序的HTTP请求报文和响应报文
注: HTTP/1.0时是可以通过设置请求头达成这种效果,HTTP/1.1是把他写入了标准
- 持久性连接:
Connection:keep-alive- 非持久性连接:
Connection: close
-
这里的持续连接有两种方式
- 非流水线方式(
without pipelining):客户端在收到前一个响应后才能发出下一个请求,也就是说必须你来我回,休想插队 - 流水线方式(
with pipelining):客户端在收到响应报文之前就可以继续接着发请求,所以服务器可以连续地返回响应报文(必须按照先后顺序排队),也就是说,你尽管发,但是我返给你就要排好队(增加的管线化技术)
- 非流水线方式(
排队问题就肯定会出现比如说,某个响应迟迟不能发回,这就会导致后面的响应需要等待很久的时间,显然不是我们所期望的
- 于是乎,
HTTP/2又站出来了,既然你一个通道排队不够用,那么我就允许你并行的返回服务端响应,这样就算有捣蛋鬼需要花长时间的时间响应也不会阻塞到其他响应的返回
二、数据相关
- 我们最初的网页是以文本为主,所以在
HTTP/1.1的时候,采用的请求和响应报文是面向文本的倒也没啥问题
还是有点问题的,比如空白字符,回车行,大小写等容易出现多义性
- 但是很快就发展到了使用大量的图片,音频,视频,同时我们所期望的实时性要求也在提高
- 于是
HTTP2又站出来了,它把所有的报文都划分为很多较小的二进制编码的帧,便于机器解码 - 首部信息会被封装到
Headers帧,而请求头则封装到Data帧里面 - 在客户端和服务端之间,双方都可以互相发送二进制帧,
HTTP/2定义了一个流(Stream)的概念,指的就是二进制帧的双向传输序列,也就是同一个消息往返的所有帧,同时给他分配了一个唯一标志Stream ID - 那么你也许会产生疑问,乱序的二进制帧,怎么能拿到我们想要的报文
- 那么首先就要分清乱序,乱的是什么序,我们指的是不同ID的
Stream可以乱序,但是对于同一个Stream的二进制帧它是有序的 - 那么就可以将相同的
Stream ID的二进制帧组装成完整的请求报文和响应报文
- 那么首先就要分清乱序,乱的是什么序,我们指的是不同ID的
HTTP/2是向后兼容的,如果使用
HTTP/2的客户向仍使用HTTP/1.1的服务器发出请求时,服务器仍然可以收到请求报文,在发出响应后,客户就会改用HTTP/1.1进行交互
三、头信息压缩
- 因为HTTP协议是不带有状态的,所以我们请求都会带上很多信息,比如说
User-Agent、Cookie、Accept、Sever、Range - 但是很多字段都是重复的,如果每一次都进行携带的话,无疑会浪费比较多的带宽,有时候
Body可能只有几十个字节,头部却占用了几百甚至几千字节,典型的头重身体轻 - 所以
HTTP/2使用了HPACK算法 - 大概就是客户端和服务端是会同时维护一张头信息表(键值对)的,这张表内可以存入字段,生成索引号
- 如果请求中不包含首部, 那么 首部开销就是零字节。此时所有首部都自动使用之前请求发送的首部
- 如果首部发生变化了,那么只需要发送变化了数据在
Headers帧里面,新增或修改的首部帧会被追加到 “头信息表”
四、Host
HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名,也就是说它默认一个IP地址就对应一个主机- 但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(
Multi-homed Web Servers),并且它们共享一个IP地址 - 那么
HTTP1.1又站出来了,它必须在Host首部内完整地指定主机名或域名的URI。如果请求消息中如果没有Host头域会报告一个错误(400 Bad Request)
Host首部字段在HTTP/1.1作为唯一一个必须被包含在请求内的首部字段
五、请求方法
HTTP/1.0的时候有GET,POST,HEAD,PUT,DELETE,Link,UNLINE- GET:获取资源
- POST:传输实体主体
- HEAD:获得报文首部
- PUT:传输文件
- DELETE:删除文件
HTTP/1.1增加了OPTIONS,TRACE,CONNECT这三个方法,还废除了Link,UNLINE这两个方法- OPTIONS:咨询支持的方法
- TRACE:追踪路径,用来确认连接过程中发送的一系列的操作
- CONNECT:要求用隧道协议连接代理
六、浏览器缓存
- 这个应该就是算经常提起的,有强制缓存和协商缓存
强缓存字段
- 在
HTTP/1.0的时候,采用的Expires标志过期时间,值为服务器返回该请求结果的缓存的到期时间;但是使用Expires判断是否缓存过期是通过客户端时间和Expires的值进行比较,若有一方时间不准确或者非同时区等那么就会有误差 - 于是在
HTTP/1.1新增了Cache-control字段,可以设置缓存的方式,同时采用了通过max-age=xxx设置缓存时间(相对值),表示缓存内容将在xxx秒后失效
注意: Cache-control的优先级比Expires高哦
协商缓存字段
在HTTP/1.0中主要使用 Last-Modified,If-Modified-Since 来作为缓存判断的标准
Last-Modified: 服务器在响应请求时,会告诉浏览器资源的最后修改时间If-Modified-Since- 告诉服务器如果
If-Modified-Since字段值早于资源的更新时间,则希望能够处理该请求 - 如果在指定的
If-Modified-Since字段值的日期时间之后,如果请求的资源都没有更新过的话,那么就返回状态码为304的响应
- 告诉服务器如果
在HTTP/1.1则引入了更多的缓存控制策略,例如 Etag、If-Unmodified-Since、If-Match、If-None-Match 等更多可供选择的缓存头来控制缓存策略
ETag: 是与特定资源关联的确定值,资源更新后ETag也会随之更新
形如
If-xxx这种模式的请求首部字段(例如下面几个),都可以称为是条件请求,服务器收到附带的条件后,只有判断指定条件为真的时候,才会执行请求
-
If-Unmodified-Since- 跟
If-Modified-Since的作用刚好相反, - 告诉服务器,指定的请求资源只有在字段值内指定的日期时间之后,未发送更新的情况下,才能处理请求
- 如果在指定日期之后,发生了更新,则返回412
- 跟
-
If-Match:- 只有当
If-Match的值跟ETag(实体标记)的值匹配一致的时候,服务器才会接收请求 - 否则的话返回状态码为412的响应
- 扩展:
If-Match: 可以用*指定,这种情况下服务器会忽略ETag的值,只要有资源那就可以处理
- 只有当
-
If-None-Match- 只有在
If-None-Match的字段值跟ETag值不一样的时候,才会处理该请求,跟上面If-Match的作用刚好相反
- 只有在
七、服务器推送
- 服务器推送(
server push)是HTTP/2协议里面,唯一一个需要开发者自己配置的功能 - 允许服务端推送资源给浏览器,在浏览器明确地请求之前。一个服务器经常知道一个页面需要很多附加资源,在它响应浏览器第一个请求的时候,可以开始推送这些资源。这允许服务端去完全充分地利用一个可能空闲的网络,改善页面加载时间
- 比如,浏览器只请求了
index.html,但是服务器把index.html、style.css、example.png全部发送给浏览器。这样的话,只需要一轮 HTTP 通信,浏览器就得到了全部资源,提高了性能
八、状态码
- 在
HTTP1.1中新增了24个错误状态响应码 - 如409(Conflict)表示请求的资源与资源的当前状态发生冲突
- 如410(Gone)表示服务器上的某个资源被永久性的删除。
九、总结
HTTP/1.0-->HTTP/1.1
- HTTP/1.1将长连接加入标准,一个连接可以被多个请求复用
- HTTP/1.1引入管道机制,可以同时发送多个请求而不必等待服务器的响应
- HTTP/1.1摒弃了
Link,UNLINE这两种方法,增添了OPTIONS,TRACE,CONNECT这三个方法 - HTTP/1.1增加了更多的缓存控制策略
- HTTP/1.1要求必须携带Host首部字段,指明发出请求的主机,否则报错
- HTTP/1.1新增了多个响应码
HTTP/1.1-->HTTP/2
- HTTP/2 采用了多路复用,摒弃了管道
- HTTP/2 采用二进制帧传输数据,而不是采用文本
- HTTP/2 采用了HPACK算法压缩头部
- HTTP/2 允许服务器主动向客户推送数据