HTTP 2.0
如果值相等,则返回 304 Not Modified,不会返回资源;
如果不相等,则返回 200 状态码和返回资源,并在 Response 头部加上新的 ETag 唯一标识;
如果浏览器收到 304 的请求响应状态码,则会从本地缓存中加载资源,否则更新资源。
ETag(响应头)、If-None-Match(请求头)
强ETab
强ETag值,不论实体发生多么细微的变化都会改变其值。
弱ETag
弱ETag值只用于提示资源是否相同。只有资源发生了根本改变,产生差异时才会改变ETag值。这时,会在字段值最开始处附加W/,'W/'(区分大小写)开头表示使用弱校验。
对于两个资源,强校验要求每个字节都相同才认为是同一个资源;而弱校验则把决定权交给开发者,根据需要区分的要素来生成相应的 ETag。
为什么要区分强弱呢,因为大多数情况下,确保严格的字节级别的一致性是没有必要的。例如,如果我们开启了 HTTP 压缩,那么对于一个资源的响应,压缩前和压缩后的字节就是不一致的,但通常我们只关心压缩前的 ETag
,这时就需要使用弱校验的 ETag。
两者对比
如果 HTTP 响应头部同时有 Etag 和 Last-Modified 字段的时候, Etag 的优先级更高,也就是先会判断 Etag 是否变化了,如果 Etag 没有变化,然后再看 Last-Modified。
- 精确度:ETag>Last*Modified。ETag按照内容给资源上标识,可准确感知资源的变化。Last*Modified不一
样
编辑了资源文件,但内容没改变,会造成缓存失效 Last_Modified可感知的时间单位是s,若在1s内修改了文件,不能体现出来。
- 性能上:LastModified优于Etag。LastModified只是记录一个时间点,ETag根据文件具体内容生成哈希值。
协商缓存这两个字段都需要配合强制缓存中 Cache-control 字段来使用,只有在未能命中强制缓存的时候,才能发起带有协商缓存字段的请求。
HTTP 2.0
特性
HTTP/2 协议基于 HTTPS
HTTP2.0可以说是SPDY的升级版本,与SPDY的区别如下:
- HTTP2.0支持明文HTTP传输,而SPDY强制使用HTTPS。
- HTTP2.0消息头压缩算法使用HPACK,而SPDY使用DEFLATE。
HTTP2.0主要目标是改进传输性能,实现低延迟和高吞吐量。
HTTP2.0升级改造需要考虑:
- HTTP2.0完全兼容HTTP1.x,对于不支持HTTP2.0的浏览器,NGINX会自动向下兼容
二进制分帧
HTTP/2 不再像 HTTP/1.1 里的纯文本形式的报文,而是全面采用二进制格式,头信息和数据体都是二进制,统称为帧(frame):头信息帧(Headers Frame)和数据帧(Data Frame)。
对人不友好,但是对计算机非常友好,因为计算机只懂二进制,收到报文后,无需再将明文的报文转成二进制,而是直接解析二进制报文,这增加了数据传输的效率
(因为是新增的二进制分帧层,所以叫2.0)
不改变HTTP语义,HTTP方法、状态码、URL及首部字段。改进传输性能,实现低延迟和高吞吐量
HTTP1.x解析基于文本,文本展现形式多样,要做到健壮性考虑的场景必然很多,二进制则只有0和1,更高效健壮
首部压缩
HTTP/2 会压缩头(Header)如果同时发出多个请求,他们的头是一样的或是相似的,那么,协议会消除重复的部分
HPACK算法:在客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,以后就不发送同样字段了,只发送索引号,这样就提高速度
HTTP 1.x无首部压缩,Gzip只对请求体压缩
SPDY和HTTP 2.0都支持首部压缩。使头部帧最大程度复用,减少头部大小,利于减少内存和流量
比如:第一次请求,包含头部各种信息,后来又发送另外请求,发现大部分字段可以复用,一次只发送一个当前请求特有的头部帧即可
首部表在HTTP 2.0的连接存续期始终有效,server和client共同更新
避免重复header传输,又减少需要传输的大小
- HTTP2.0会压缩首部元数据,在client和server使用首部表跟踪和存储之前发送的健值对,对于相同数据,不
需每次请求响应都发送
- 所有header必须全部小写,而且请求行要独立为健值对(即header+值)
多路复用
HTTP 1.0:建立连接请求数据完毕之后立即关闭连接;
后来采用keep-alive模式使得可以复用连接而不断开,可利用这次连接继续请求数据
缺点:必须等到server返回上一次的请求数据才可以进行下一次请求
Q:遇到一个请求很久没有响应,后面的请求只能等待?
HTTP/2 是可以在一个连接中并发多个请求或回应,而不用按照顺序一一对应。
多路复用(MultiPlexing),即连接共享,每一个request都是用作连接共享机制的。每一个request对应一个id,一个连接上可以有多个request,每个连接的request可以随机的混杂在一起,接收方根据request的id将request再
归属到不同服务端请求里面。客户端只需要一个连接就可以加载一个页面
举例来说,在一个 TCP 连接里,服务器收到了客户端 A 和 B 的两个请求,如果发现 A 处理过程非常耗时,于是就回应 A 请求已经处理好的部分,接着回应 B 请求,完成后,再回应 A 请求剩下的部分
优点:
- 并行交错发送请求,请求之间互不影响
- TCP连接一旦建立可并行发送请求
- 消除不必要延迟,减少页面加载时间
- 可最大程度利用HTTP 1.x
请求优先级
server根据流的优先级控制资源分配,响应数据准备好后,把优先级最高的帧发送给client。browser发现资源时立即分派请求,指定每个流的优先级,让服务器决定最优的响应次序,这时请求不用排队,节省时间,最大限度利用
连接
流量控制
流:不改变协议,允许采用多种流量控制算法
特点:
- 流量基于HTTP连接的每一跳进行,不是端到端控制
- 流量基于窗口更新帧进行,接收方可广播准备接收字节甚至对整个连接要接收的字节数
- 流量控制有方向,接收方根据自身情况控制窗口大小
- 流量控制可由接收方禁用
- 只有data帧服从流量控制,其他不会消耗控制窗口的空间
服务端推送
HTTP/2 在一定程度上改善了传统的「请求 - 应答」工作模式,服务不再被动响应,也可以主动向客户端发送消息
server push通过推送那些它认为客户端将会需要使用到的内容到客户端缓存中,以此避免往返的延迟
- 客户端可以限定推送流的数量,也可以设置为0而完全禁用server push
- 所有推送遵守同源策略,即服务器不能随便将第三方资源推送给客户端,必须是经过双方确认的
- PUSH_PROMISE帧:所有服务器推送流都通过PUSH_PROMISE发送,服务端发出有意push所述资源的信
号,客户端接收到PUSH_PROMISE帧后,也可以拒绝这个流
- 服务端必须遵循请求-响应的循环,只能借着对请求的响应推送资源。
- PUSH_PROMISE帧必须在返回响应之前发送,否则客户端会出现竞态条件。
数据流
HTTP/2 的数据包不是按顺序发送,同一个连接里面连续的数据包,可能属于不同回应。因此,必须要对数据包做标记,指出它属于哪个回应
在 HTTP/2 中每个请求或相应的所有数据包,称为一个数据流(Stream)。每个数据流都标记着一个独一无二的编号(Stream ID),不同 Stream 的帧可以乱序发送(因此可以并发不同Stream),因为每个帧的头部会携带
Stream ID 信息,所以接收端可以通过 Stream ID 有序组装成 HTTP 消息
客户端和服务器双方都可以建立 Stream, Stream ID 也有区别,客户端建立的 Stream 必须是奇数号,而服务器
HTTP/2 通过 Stream 的并发能力,解决了 HTTP/1 队头阻塞的问题,看似很完美了,但是 HTTP/2 还是存在“队头阻塞”的问题,只不过问题不是在 HTTP 这一层面,而是在 TCP 这一层。
HTTP/2 是基于 TCP 协议传输数据,TCP 是字节流协议,TCP 层必须保证收到的字节数据完整且连续,这样内核才会将缓冲区里的数据返回给 HTTP 应用,当「前 1 个字节数据」没有到达时,后收到的字节数据只能存放在内核
缓冲区里,只有等到这 1 个字节数据到达时,HTTP/2 应用层才能从内核中拿到数据—— HTTP/2 队头阻塞问题。

图中发送方发送了很多个 packet,每个 packet 都有自己的序号,可以认为是 TCP 的序列号,其中 packet 3 在网络中丢失了,即使 packet 4-6 被接收方收到后,由于内核中的 TCP 数据不连续,于是接收方的应用层无法从内核
中读取,只有等到 packet 3 重传后,接收方的应用层才可以从内核中读取到数据——HTTP/2 的队头阻塞问题,发生在 TCP 层面
所以,一旦发生了丢包现象,就会触发 TCP 重传机制,这样在一个 TCP 连接中的所有的 HTTP 请求都必须等待这
全站分卷索引 · 154 卷
- 1代码随想录知识星球精华(最强八股文)第五版(前端篇))
- 2html语义化
- 3src 和 href 的区别
- 4link 与 @import 的区别
- 5iframe
- 6CSS
- 7伪元素和伪类
- 8block,inline,inline-block
- 9重排、重绘和合成
- 10盒子模型
- 11margin 合并
- 12margin和padding 的值为百分比时
- 13浮动
- 14定位
- 15CSS选择器
- 16CSS选择器优先级
- 17选择器权重Specificity
- 18CSS属性继承
- 19不可/可继承属性
- 20display: none与 visibility: hidden的区别
- 21background-size
- 22client、offset&scroll
- 23CSS3新特性
- 24flex布局
- 25常见布局
- 26三栏布局
- 27垂直居中
- 28水平垂直居中
- 29CSS画三角形
- 30使chrome支持12px以下文字
- 31响应式布局
- 32媒体查询
- 33过渡与动画
- 34JavaScript 动画 和 CSS动画
- 35SCSS
- 36CSS性能优化
- 37有哪些数据类型
- 38判断数据类型
- 39类型转换
- 40parseInt&parseFloat
- 41浮点数求和步骤
- 42十进制小数转二进制
- 430.1+0.2 为什么不等于 0.3
- 44undefined 和 undeclared 的区别
- 45JavaScript NaN 属性
- 46isFinite()&isNaN()
- 47数组
- 48对原数组有影响
- 49对原数组无影响
- 50数组去重
- 51数组拍平
- 52ES6新增的数组方法
- 53判断是否存在某个值
- 54arguments为啥不是数组
- 55对象
- 56遍历对象的方法
- 57判断对象是否具有属性
- 58for in 和 for of 的区别
- 59继承方式
- 60instanceof
- 61深浅拷贝
- 62freeze属性
- 63函数
- 64函数柯里化
- 65函数的 length
- 66箭头函数和普通函数区别
- 67构造函数
- 68执行上下文
- 69作用域
- 70作用域和作用域链
- 71闭包和内存泄漏
- 72this
- 73关于 this 的指向问题
- 74改变this指向的方法(bind / call / apply)
- 75字符串
- 76DOM和事件
- 77哪些事件支持冒泡
- 78阻止冒泡
- 79HTMLCollection、NodeList
- 80dom.onclick 和 dom.addEventListener的区别
- 81e.target和e.currentTarget
- 82页面生命周期
- 83异步
- 84内存管理GC
- 85其它
- 86JavaScript 中日期时间格式转换
- 87input和object实现双向绑定
- 88JSON.stringify()
- 89escape、encodeURI&encodeURIComponent
- 90移动端滚动穿透和溢出
- 91ES6
- 92Map字典
- 93... 与rest
- 94proxy
- 95模块化
- 96Ajax、Fetch和Axios
- 97Webpack
- 98浏览器:事件循环
- 99浏览器内核
- 100浏览器同源策略
- 101输入URL回车后发生了什么
- 102HTTP
- 103HTTP 2.0
- 104浏览器存储
- 105鉴权
- 106Webstorage
- 107浏览器执行机制
- 108AST 抽象语法树
- 109性能优化
- 110CSS
- 111网络相关
- 112使用HTTP2.0
- 113图片
- 114CDN图片
- 115其他文件优化
- 116降低APP首页开屏渲染时间
- 117页面白屏
- 118HTTPS中间人攻击
- 119Web Worker
- 120Service Worker
- 121微前端
- 122Vue
- 123v-show 和 v-if 的区别
- 124双向数据绑定的原理
- 125Vue中的插槽使用
- 126Vue中的key
- 127Vue过滤器
- 128Vue中Scoped原理
- 129Vue中$nextTick的使用
- 130Vue中实现组件通信的方式
- 131Vue-router
- 132Vue路由传参
- 133前端路由
- 134Vuex
- 135虚拟DOM
- 136DIFF 算法
- 137Vue3和Vue2有哪些区别
- 138说一说你对React的理解
- 139React事件机制
- 140说一说你对react refs的理解
- 141react中key的作用
- 142组件开发
- 143有状态组件和无状态组件
- 144函数式组件和类组件的区别
- 145PureComponent&Component
- 146常见 Hooks
- 147状态管理
- 148redux toolkit
- 149React18新特性
- 150client中的createRoot取代以前的ReactDOM.render
- 151Suspense
- 152新的Hooks
- 153VDom一定更快吗
- 154Fiber