Skip to content

HTTP #24

Description

@Ben-yby

常见的状态码有哪些

HTTP状态码分为5类:

  • 1xx表示继续发送请求;
  • 2xx表示请求成功;
  • 3xx表示资源已找到但需要继续进行其他操作;
  • 4xx表示客户端错误;
  • 5xx表示服务器错误。

HTTP状态码

304代表什么,和302有什么区别

302

重定向,当响应码为302时,表示服务器要求浏览器重新再发一个请求,服务器会发送一个响应头Location,它指定了新请求的URL地址;

304

  1. 当用户第一次请求index.html时,服务器会添加一个名为==Last-Modified==响应头,这个头说明了index.html的最后修改时间,浏览器会把index.html内容,以及最后响应时间缓存下来。
  2. 当用户第二次请求index.html时,在请求中包含一个名为==If-Modified-Since==请求头,它的值就是第一次请求时服务器通过==Last-Modified==响应头发送给浏览器的值,即index.html最后的修改时间,浏览器会进行比较:
  • 如果相匹配服务器会发响应码304,表示index.html与浏览器上次缓存的相同,无需再次发送(节省传输成本),浏览器可以显示自己的缓存页面.
  • 如果比对不同,那么说明index.html已经做了修改,服务器会响应200。

总结:

  • 302重定向(两次请求) 。
  • 304,浏览器缓存的上次请求的.html页面,包括最后修改时间(如果发现最后修改时间和服务器里面的时间一样,那么响应304,无需传输数据,浏览器接收到304,则去自己的缓存中取出数据,节省传输成本)

Connection为Keep-alive表示什么

什么是Keep-Alive模式?

  • 当使用普通模式,即非KeepAlive模式时,每个请求/应答客户和服务器都要新建一个连接,完成之后立即断开连接(HTTP协议为无连接的协议);
  • 当使用Keep-Alive模式(又称持久连接、连接重用)时,Keep-Alive功能使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接。

image

  • http 1.0中默认是关闭的,需要在http头加入"Connection: Keep-Alive”,才能启用Keep-Alive;
  • http 1.1中默认启用Keep-Alive,如果加入"Connection: close “,才关闭。目前大部分浏览器都是用http1.1协议,也就是说默认都会发起Keep-Alive的连接请求了,所以是否能完成一个完整的Keep- Alive连接就看服务器设置情况。

HTTP 2.0 和 HTTP1.1 和 HTTP1.0 区别

HTTP1.0和HTTP1.1区别

内容 HTTP1.0 HTTP1.1
连接方面 使用 非持久连接,即在非持久连接下,一个tcp连接只传输一个web对象。每次请求和响应都需要建立一个单独的连接,每次连接只是传输一个对象,严重影响客户机和服务器的性能 HTTP1.1默认使用持久连接在持久连接下,不必为每个Web对象的传送建立一个新的连接,一个连接中可以传输多个对象。在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。
缓存方面 主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准 引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略带宽优化及网络连接的使用
状态码 无状态 新增了24个错误状态响应码
宽带优化 存在一些浪费带宽的现象,例如客户端只是需要某个对象一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能 支持只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器,则返回100,否则返回401。客户端如果接收到100,才开始把请求body发送到服务器。这样当服务器返回401的时候,客户端就可以不用发送请求body了,节约了带宽。
Host头 HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。 HTTP1.1的请求消息和响应消息都应支持Host头域,且请求消息中如果没有Host头域会报告一个错误(400 Bad Request)

HTTP1.0和HTTP1.1现存的问题

  1. HTTP1.x在传输数据时,每次都需要重新建立连接,无疑增加了大量的延迟时间,特别是在移动端更为突出
  2. HTTP1.x在传输数据时,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份,无法保证数据的安全性
  3. HTTP1.x在使用时,header里携带的内容过大,增加了传输的成本,并且每次请求header基本不怎么变化,尤其在移动端增加用户流量
  4. 虽然HTTP1.x支持了keep-alive,来弥补多次创建连接产生的延迟,但是keepalive使用多了同样会给服务端带来大量的性能压力,并且对于单个文件被不断请求的服务(例如图片存放网站),keep-alive可能会极大的影响性能,因为它在文件被请求之后还保持了不必要的连接很长时间

HTTP2.0特性

  • 头信息和数据体都是二进制,称为头信息帧和数据帧
  • 复用TCP连接,在一个连接里,客户端和浏览器都可以同时发送多个请求或回应,且不用按顺序一一对应,避免了“队头堵塞“,此双向的实时通信称为多工(Multiplexing)
  • 引入头信息压缩机制(header compression),头信息使用gzip或compress压缩后再发送;客户端和服务器同时维护一张头信息表,所有字段都会存入这个表,生成一个索引号,不发送同样字段,只发送索引号,提高速度
  • HTTP/2 允许服务器未经请求,主动向客户端发送资源,即服务器推送(server push)

HTTP1.1和HTTP2.0的区别

内容 HTTP1.1 HTTP2.0
多路复用 在HTTP/1.1协议中,浏览器客户端在同一时间针对同一域名的请求有一定数据(6个TCP连接)限制。超过限制数目的请求会被阻塞() HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。而这个强大的功能则是基于“二进制分帧”的特性。
首部压缩 不支持header数据的压缩 使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快
服务器推送 不支持服务器推送 当我们对支持HTTP2.0的web server请求数据的时候,服务器会顺便把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器端获取。

对比参考连接

HTTP的缓存策略

为什么需要浏览器缓存

  • 通过从输出 URL 到页面呈现我们可以知道,浏览器如果每次都要请求加载页面,会相当费时间。
  • 而如果我们将某些网页存储到浏览器缓存中,这样当我们打开一个网页的时候,就会去查询浏览器缓存,看是否有请求的文件。
  • 如果有,那就拦截请求,返回缓存文件,并结束请求,而不会去服务器下载。

什么是浏览器缓存

  • 意思就是,浏览器缓存保存着用户通过 HTTP 获取的所有资源,再下一次请求时可以避免重复向服务器发出多余的请求。
  • 通俗的说,就是在你访问过一次某个网站之后,这个站点的文字、图片等所有资源都被下载到本地了,下次再访问该网站时判断是否满足缓存条件,如果满足就不用再花费时间去等待资源的获取了。

为什么需要浏览器缓存淘汰策略

  • 浏览器中的缓存是一种本地保存资源副本,它的大小是有限的,当我们请求次数过多的时候,缓存空间就会被塞满,这个时候,就需要判断哪些缓存数据需要被保留,哪些数据需要被清理。
  • 浏览器缓存也有属于自己的策略:==浏览器缓存淘汰策略==。
  • 最常见的淘汰策略有 FIFO(先进先出)、LRU(最近最少使用)、LFU(最少使用)。
FIFO(先进先出)

如果一个数据是最先进入的,那么可以认为在将来它被访问的可能性很小。空间满的时候,最先进入的数据会被最早置换(淘汰)掉。

LRU(最近最少使用)

如果一个数据在最近一段时间没有被访问到,那么可以认为在将来它被访问的可能性也很小。因此,当空间满时,最久没有访问的数据最先被置换(淘汰)。

LFU(最少使用)

如果一个数据在最近一段时间很少被访问到,那么可以认为在将来它被访问的可能性也很小。因此,当空间满时,最小频率访问的数据最先被淘汰。

浏览器缓存的分类

一般来说浏览器缓存可以分为两类:

  • 强缓存
  • 协商缓存(对比缓存)

我们需要知道的是,浏览器在加载资源时,会先判断是否命中==强缓存==再验证是命中==协商缓存==。

强缓存

浏览器在加载资源时,会先根据本地缓存资源的 header 中的信息判断是否命中强缓存,如果命中则直接使用缓存中的资源不会再向服务器发送请求。

流程:
  1. 查看 header 头中的 Expire 和 Cache-control 来判断是否满足规则;
  2. 如果满足规则,就返回缓存的数据;
  3. 如果不满足规则,就向服务器发送请求;
  4. 服务器返回数据;
  5. 将新数据存入缓存。
Expire
  • Expire包含了一个时间,过了这个时间,响应将会失效。
  • Expire设置的是绝对时间( Expires:Fri, 27 Oct 2017 07:55:30 GMT),如果修改了客户端的本地时间,会导致判断缓存失效。
Cache-control

在 HTTP/1.1 中,增加了一个字段 Cache-Control ,它包含一个 max-age 属性,该字段表示资源缓存的最大有效时间,这就是一个相对时间。

  • no-cache:需要进行协商缓存,发送请求到服务器确认是否使用缓存。
  • no-store:禁止使用缓存,每一次都要重新请求数据。
  • public:默认设置。
  • private:不能被多用户共享。

现在基本上都会同时设置 Expire 和 Cache-Control ,Cache-Control 的优先级别更高。

协商缓存

当强缓存没有命中的时候,浏览器会发送一个请求到服务器,服务器根据请求头中的部分信息来判断是否命中缓存。如果命中,则返回 304 ,告诉浏览器资源未更新,可使用本地的缓存。

流程:
  1. 把资源标识,比如 If-Modify-Since 或 Etag 发送到服务器,确认资源是否更新;
  2. 如果资源未更新,请求响应返回的http状态为 304 并且会显示一个 Not Modified 的字符串,告诉浏览器使用本地缓存;
  3. 如果资源已经更新,返回新的数据;
  4. 将新数据存入缓存。
Last-Modified,If-Modified-Since

浏览器第一次请求资源的时候,服务器返回的 header 上会带有一个 Last-Modified 字段,表示资源最后修改的时间(Last-Modified: Fri, 27 Oct 2017 07:55:30 GMT)。

  • 当浏览器再次请求该资源时,请求头中会带有一个 If-Modified-Since 字段,这个值是第一次请求返回的 Last-Modified 的值。
  • 服务器收到这个请求后,将 If-Modified-Since 和当前的 Last-Modified 进行对比。如果相等,则说明资源未修改,返回 304,浏览器使用本地缓存。

缺点:

  • 最小单位是秒。也就是说如果我短时间内资源发生了改变,Last-Modified 并不会发生变化;
  • 周期性变化。如果这个资源在一个周期内修改回原来的样子了,我们认为是可以使用缓存的,但是 Last-Modified 可不这样认为。
Etag

Etag 一般是由文件内容 hash 生成的,也就是说它可以保证资源的唯一性,资源发生改变就会导致 Etag 发生改变。

  • 同样地,在浏览器第一次请求资源时,服务器会返回一个 Etag 标识。
  • 当再次请求该资源时, 会通过 If-None-match 字段将 Etag 发送回服务器,然后服务器进行比较,如果相等,则返回 304 表示未修改。

Last-Modified 和 Etag 是可以同时设置的,服务器会优先校验 Etag,如果 Etag 相等就会继续比对 Last-Modified,最后才会决定是否返回 304.

当浏览器再次访问一个已经访问过的资源时,它会这样做:

  • 看看是否命中==强缓存==,如果命中,就直接使用缓存了;
  • 如果没有命中==强缓存==,就发请求到服务器检查是否命中==协商缓存==;
  • 如果命中==协商缓存==,服务器会返回304告诉浏览器使用本地缓存;
  • 否则,返回最新的资源。

缓存位置

Service Worker
  • Service Worker 是运行在浏览器背后的独立线程,一般可以用来实现缓存功能。
  • 必须是 HTTPS。因为它涉及请求拦截,所以必须使用 HTTPS 协议来保障安全。
  • Service Worker 缓存不同于其他机制,它可以让我们自由控制缓存哪些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。
Memory Cache
  • Memory Cache:内存中的缓存,主要是页面上已经下载的样式、脚本、图片等已经抓取到的资源。
  • 读取内存中的数据肯定比磁盘快,读取高效。
  • 缓存持续性很短,会随着进程的释放而释放。关闭页面内存中的缓存也就释放了。
Disk Cache
  • Disk Cache 是存储在硬盘中的缓存,读取速度相对慢点。
  • 比起 Memory Cache 胜在容量和存储时效性上。
Push Cache
  • Push Cache(推送缓存) 是 HTTP/2 中的内容,当以上 3 种缓存都没有命中的时候,它才会被使用。
  • 它只在会话(Session)中存在,一旦会话结束就被释放,并且缓存也很短暂。

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions