浏览器缓存
#积累/浏览器原理
缓存查找流程
- 发起资源请求,首先浏览器会在浏览器缓存中查找是否有请求的文件,如果有缓存的文件,且缓存未过期,则使用缓存;
- 如果没有缓存该文件,则向服务器发起请求,服务器直接响应内容;
- 如果有缓存的文件,但缓存时间过期,则携带缓存文件标识符正式发起请求。服务器根据标示符比对文件是否有更新,如果未修改,则响应304,使用过期缓存;如果已经更新,则直接响应内容。
什么是强制缓存和协商缓存?
强制缓存就是向浏览器缓存查找该请求结果,并根据该结果的缓存规则来决定是否使用该缓存结果的过程。
协商缓存就是强制缓存失效后,浏览器携带缓存标识向服务器发起请求,由服务器根据缓存标识决定是否使用缓存的过程
服务器是通过什么方式让浏览器缓存数据的?
::Cache-Control / Expires::
当服务器返回 HTTP 响应头给浏览器时,浏览器是通过响应头中的 Cache-Control字段(HTTP/1.1)或Expires字段(HTTP/1.0)来设置是否缓存该资源。
比如上图设置的缓存过期时间是 2000 秒:
1 | Cache-Control:Max-age=2000 |
也根据Cache-Control或Expires来判断资源是否过期,如果未过期则使用缓存文件,如果过期则正式发起请求
- Cache-Control和Expires同时存在时,只有Cache-Control生效。
服务器如何比对资源是否修改?
::Last-Modified / If-Modified-Since::
Last-Modified是服务器响应请求时,返回该资源文件在服务器最后被修改的时间;
If-Modified-Since则是客户端再次发起请求时,携带上次请求返回的Last-Modified值,通过此字段值告诉服务器该资源上次请求返回的最后被修改时间;
服务器根据If-Modified-Since信息和该资源在服务器的最后被修改时间,判断响应304,还是响应新内容。
::Etag / If-None-Match::
Etag是服务器响应时,返回当前资源文件的一个唯一标识(由服务器生成);
If-None-Match是浏览器发现缓存过期再次请求时,携带的上次请求返回的唯一标识Etag值;
服务器根据If-None-Match的字段值与该资源在服务器的Etag值做对比,如果文件未更新则响应304,如果已更新则响应新内容。
- Etag / If-None-Match优先级高于Last-Modified / If-Modified-Since,同时存在则只有Etag / If-None-Match生效。
Ctrl+F5和F5有什么区别?
- 一个是强制刷新,也就是资源都走网络。
- 一个是正常处理流程,缓存机制还起作用。还包括这些浏览器操作:在URI输入栏中输入地址并回车、右键菜单重新加载、点击工具栏中的刷新按钮
其他
Cache-control参数
Cache-Control
定义资源的缓存策略
- no-cache, no-store
no-cache: 浏览器不做缓存,每次请求资源都会发起请求,etag没有变化、服务器返回304,则不再重新下载资源;
no-store:浏览器和cdn均不做缓存,并且每次请求资源都会发起请求,并重新下载资源。 - public, private
当存在私密信息、时效性高的数据,则需要设置。
public: 可以缓存,即使保护用户隐私信息;
private:不允许cdn缓存,防止用户信息泄露。 - max-age
指定从请求开始,允许被重用的最长时间(单位秒)。
当设置了max-age,资源在指定的时间内不会发送请求到服务器 - 例子
max-age=86400:
浏览器以及任何中间缓存均可将响应(如果是“public”响应)缓存长达 1 天(60 秒 x 60 分钟 x 24 小时)。
private, max-age=600:
客户端的浏览器只能将响应缓存最长 10 分钟(60 秒 x 10 分钟)。
no-store:
不允许缓存响应,每次请求都必须完整获取。 - nginx配置cache-control
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16location ~ .*\.(css|js|swf|php|htm|html )$ {
add_header Cache-Control no-store;
add_header Pragma no-cache;
}
location ~* \.(gif|jpg|jpeg|bmp|png|ico|txt|js|css)$ {
expires 30d;
}
location ~* \.html?$ {
expires 10m;
}
最终响应中会添加以下属性:
* ### Cache-Control:max-age=600
* ### Expires:Sat, 23 Mar 2019 14:37:35 GMT
* ### ETag:"5c962c53-15b"
* ### Last-Modified:Sat, 23 Mar 2019 12:53:39 GMT
配置Etag
- 服务器会响应ETag,去唯一标示资源。当资源有变化,ETag也会改变。
- 客户端收到ETag之后,浏览器会在请求头中加入If-None-Match,传递ETag值。
- 服务器比对ETag,发现没有变化,则可以通过响应304 Not Modified,来避免重新下载资源。
- nginx开启ETag
1
2
3
4
5http{
...
etag on;
...
}
缓存策略
- 入口文件设置no-cache,不做缓存;
- 所有图片、静态文件,都做长时间的缓存
- 所有图片、静态文件,文件名设置hash值,并每天更新同时更改入口文件的引入文件名