liuqinh2s' blog

Do something cool!

参考

https://github.com/amandakelake/blog/issues/41

概述

基本原理

浏览器在请求资源的时候,根据请求头的 expires 和 cache-control 判断是否命中强缓存,是则直接从缓存读取资源,不会发请求到服务器。

如果没有命中强缓存,浏览器一定会发送一个请求到服务器,通过 last-modified 和 etag 验证资源是否命中协商缓存,如果命中,服务器会将这个请求返回,但是不会返回这个资源的数据,依然是从缓存中读取资源。

如果前面两者都没命中,直接从服务器加载资源。

相同点

如果命中,都是从客户端缓存中加载资源,而不是从服务器加载资源数据。

不同点

强缓存不发请求到服务器,协商缓存会发请求到服务器。

强缓存

强缓存通过 Expires 和 Cache-Control 两种响应头实现

Expires

Expires 是 Http1.0 提出的一个表示资源过期时间的 header,它描述的是一个绝对时间,由服务器返回。

Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效。

1
Expires: Wed, 11 May 2018 07:20:00 GMT

Cache-Control

Cache-Control 出现于 HTTP/1.1,优先级高于 Expires,表示的是相对时间

1
Cache-Control: max-age=315360000

max-age再结合客户端接收到响应的客户端系统时间,就可以算出实际的客户端过期时间。哪怕一开始时间不准也没关系。比Expires这种绝对时间要好一点

Cache-Control: no-cache 不会缓存数据到本地的说法是错的,详情《HTTP 权威指南》P182

Cache-Control: no-store 才是真正的不缓存数据到本地

Cache-Control: public 可以被所有用户缓存(多用户共享),包括终端和 CDN 等中间代理服务器

Cache-Control: private 只能被终端浏览器缓存(而且是私有缓存),不允许中继缓存服务器进行缓存

协商缓存

当浏览器对某个资源的请求没有命中强缓存,就会发一个请求到服务器,验证协商缓存是否命中,如果协商缓存命中,请求响应返回的 http 状态为 304 并且会显示一个 Not Modified 的字符串。

协商缓存是利用的是【Last-Modified, If-Modified-Since】和【ETag、If-None-Match】这两对 Header 来管理的

Last-Modified, If-Modified-Since

Last-Modified 表示本地文件最后修改日期,浏览器会在 request header 加上 If-Modified-Since(上次返回的 Last-Modified 的值),询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来

但是如果在本地打开缓存文件,就会造成 Last-Modified 被修改,所以在 HTTP/1.1 出现了 ETag

ETag、If-None-Match

ETag 就像一个指纹,资源变化都会导致 ETag 变化,跟最后修改时间没关系,ETag 可以保证每一个资源是唯一的

If-None-Match 的 header 会将上次返回的 ETag 发送给服务器,询问该资源的 ETag 是否有更新,有变动就会发送新的资源回来

ETag 的优先级比 Last-Modified 更高

具体为什么要用 ETag,主要出于以下几种情况的考虑:

  • 一些文件会周期性的更改,但它的内容并不改变(只改变修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新 GET
  • 某些文件修改非常频繁,比如在秒以下的时间内进行修改(比方说 1s 内修改了 N 次),If-Modified-Since 能检查到的粒度是秒级的,这种修改无法判断(UNIX 记录 MTIME 只能精确到秒)
  • 某些服务器不能精确的得到文件的最后修改时间。

整体流程图

几种状态码的区别

  • 200:强缓存 Expires/Cache-Control 失效时,返回新的资源文件
  • 200(from cache):强缓存 Expires/Cache-Control 都存在,未过期,Cache-Control 优先于 Expires 时,浏览器从本地获取资源成功
  • 304(Not Modified):协商缓存 Last-Modified/ETag 没有过期时,服务器返回状态码 304

但是!但是!

现在的 200(from cache)已经变成了 from disk cache(磁盘缓存)和 from memory cache(内存缓存)两种,打开 chrome 控制台看一下网络请求就知道了

具体两者的区别,暂时没有去深究,有兴趣的同学可以自己去研究

如何选择合适的缓存

大致的顺序

  • Cache-Control,请求服务器之前
  • Expires,请求服务器之前
  • If-None-Match(ETag),请求服务器
  • If-Modified-Sine(Last-Modified),请求服务器

协商缓存需要配合强缓存使用,如果不启用强缓存的话,协商缓存根本没有意义。

大部分 web 服务器都默认开启协商缓存,而且是同时启用【Last-Modified,If-Modified-Since】和【ETag,If-None-Match】

但是下面的场景需要注意:

  • 分布式系统里多台机器间文件的 Last-Modified 必须保持一致,以免负载均衡到不同机器导致比对失败
  • 分布式系统应尽量关闭掉 ETag(每台机器生成的 ETag 都会不一样)

使用上的区别

  • GET 请求参数放在 URL 上,POST 请求参数放在请求体里
  • GET 请求参数长度有限制,POST 请求的参数长度可以非常大
  • POST 请求相对 GET 请求来说安全一点,因为 GET 请求参数在 URL 上,而且有历史记录
  • GET 请求能缓存,POST 请求不能

本质区别

其实 HTTP 协议并没有要求 GET/POST 请求参数必须放在 URL 上或请求体里,也没有规定 GET 请求的长度,目前对 URL 的长度限制,是各家浏览器设置的限制。GET 和 POST 的根本区别在于:GET 请求是幂等的,而 POST 请求不是。

幂等性,指的是对某一个资源进行一次或多次请求都具有相同的副作用。例如搜索就是一个幂等的操作,而删除、新增则不是一个幂等操作。

由于 GET 请求是幂等的,在网络不好的环境中,GET 请求可能会重复尝试,造成重复操作数据的风险,因此,GET 请求一般用于无副作用的操作(如搜索),新增/删除等操作适用于 POST。

  1. HTTP 使用 80 端口,HTTPS 使用 443 端口
  2. HTTPS 需要申请证书
  3. HTTP 是超文本传输协议,是明文传输;HTTPS 是经过 SSL 加密的协议,传输更安全
  4. HTTPS 比 HTTP 慢,因为 HTTPS 除了 TCP 握手的三个包,还要加上 SSL 握手的 9 个包

HTTPS 的加密过程

参考

https://blog.csdn.net/xiaopang_yan/article/details/78709574

https://www.ruanyifeng.com/blog/2014/09/ssl-latency.html

加密者,解密者

对称加密

使用同一份密钥

非对称加密

加密者使用私钥加密,解密者用公钥解密,没有私钥,解不开用公钥加密的内容。

数字证书

操作系统内置数字证书,其目的是提前把值得信赖的公钥获取到,保证了公钥的真实。

HTTPS 的 SSL 握手流程

客户端 → 服务器:你好

服务器 → 客户端:你好,我是服务器,这是我的数字证书

客户端 → 服务器:向我证明你就是我要访问的服务器

服务器 → 客户端:hello world{hello wolrd}[私钥|RSA]

{}中的内容是非对称加密后的内容,[|]表示用什么私钥,什么加密算法,进行加密

客户端 → 服务器:{我们后面的通信过程,用对称加密来进行,算法:xxx,密钥:xxx}[公钥|RSA]

服务器 → 客户端:{收到}[密钥|对称加密算法]

客户端 → 服务器:{我的账号是:xxx,密码是:xxx,把我的余额发送给我看看}[密钥|对称加密算法]

服务器 → 客户端:{你的余额是:xxx}[密钥|对称加密]

2XX 请求成功

200 OK : 客户端发送给服务器的请求被正常处理并返回

3XX 重定向

301 Moved Permanently:永久重定向,请求的网页已永久移动到新位置。服务器返回此响应时,会自动将请求者转到新位置。

302 Moved Temporarily:临时重定向,请求的网页已临时移动到新位置。服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。

304 Not Modified:未修改,自从上次请求后,请求的网页未修改过。服务器返回此响应时,不会返回网页内容。

4XX 客户端错误

400 Bad Request:错误请求,服务器不理解请求的语法,常见于客户端传参错误。

401 Unauthorized:未授权,表示发送的请求需要有通过 HTTP 认证的认证信息,常见于客户端未登录。

403 Forbidden:禁止,服务器拒绝请求,常见于客户端权限不足

404 Not Found:未找到,服务器找不到对应资源

5XX 服务端错误

500 Inter Server Error:服务器内部错误,服务器遇到错误,无法完成请求

501 Not Implemented:尚未实施,服务器不具备完成请求的功能

502 Bad Gateway:作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应

503 service unavailable:服务不可用,服务器目前无法使用(处于超载或停机维护状态)。通常是暂时状态

0%