The purpose of caching is to reduce the data transmission between the client and the server, so as to reduce the pressure on the server and optimize the client experience. For example, in a site, some dependent resources may not Web
change for ten years. This kind of resource is very suitable for caching. There are generally two types of caches that are often said, strong caches and negotiation caches (weak caches)
Http1.1
protocol specification
Strong cache Cache-Control
The main use is Cache-control
the response header. For example Cache-Control:max-age=3600
, when a resource sets the request header and caches the resource again within an hour ( url
), it will not request the server again, but read directly from the cache. The screenshot above It is a script loaded by a certain page of Zhihu javascript
. It is set in the request header cache-control:max-age=31536000
. This number of seconds is converted into one year. I will not request the server again when I visit again within one year, and the browser is also requesting the status code After marked from memory cache ( from memory cache
)
Negotiation Cache Etag
When requesting a resource, the server will return a characteristic value called etag
the response header. When the validity period of the strong cache expires, the browser will automatically carry a request header named If-None-Match
, and the value is the value returned by the response header etag
. It is equivalent to accessing the server with a logo. Whether this resource should be updated at present, whether to return 200
or not 304
, depends entirely on the server.
- Return
304
, tell the client that the resource has not changed, continue to use it, and restart the calculation of the strong cache time (if it is set) - Return
200
, tell the client that the resource can be deleted, and the server will return a new resource
Build a static server for hands-on verification
For easier understanding, this nginx
is used as a simple configuration for easy testing. 8080
The port is configured as follows, which /Users/mongielee/cache-demo
is changed to its own site path. Only two files are needed in the site, one index.html
and onemain.js
server {
listen 8080;
server_name localhost;
location / {
root /Users/mongielee/cache-demo;
index index.html index.htm;
}
location ~ \.js$ {
root /Users/mongielee/cache-demo;
add_header Cache-Control max-age=10;
}
}
复制代码
这里的配置主要是add_header Cache-Control max-age=10
,该配置为所有js
后缀的资源都添加了10s
都缓存时间,文件内容如下
启动或重启nginx
服务后,访问localhost:8080
可以看到响应头中携带着文件标识etag
和强缓存比标记cache-control
,此时十秒内再次访问main.js
资源,浏览器不会再发请求而是使用内存缓存
当10
秒过后再访问main.js
,浏览器就在请求头带上If-None-Match
标记,值为上一次请求的响应头中的etag
,带上If-None-Match
这一步浏览器会自动处理,此时返回的状态码就是304
,说明文件没有被修改,此时重新计算Cache-Control
的值
如果在二次请求前,服务器文件被修改,那么在强缓存过期后,协商缓存会返回200
状态码,原因是请求头的etag
值与服务器计算的不一致,下面图中,服务端新返回的etag
是xxx-1e
,而请求头带的是xx-1a
,说明文件被修改过
Http1.0
协议规范
之所以和1.1
有不同的内容,原因是1.0
并没有设计好,与Cache-Control
和etag
相对应的是Expires
和Last-Modified
强缓存Expires
使用该响应头返回客户端一个时间值,那么导致的问题就是如果客户端修改了时间,那么缓存直接就失效了,以及需要注意的地方是,当cache-control
和expires
同时设置时,会忽略掉expires
,使用cache-control
。在Expires
的指定时间内(客户端时间),都会从缓存中读取
协商缓存If-Modified-Since
When Expires
the time expires, a request header will be added to access the resource again If-Modified-Sice
. The value is the value in the response header Last-Modified
of the last request. The server will compare the last modification time of the file with the request header If-Modified-Since
, and return if the time is found to be consistent 304
. If etag
and last-modified
are set at the same time, it takes precedence etag
, that is, 1.1
the specification of1.0
The disadvantage of this method is that the accuracy is only at the second level. If the file is modified twice (multiple times) within one second, the result will not be correct. The two time comparisons in the figure below are consistent, so the returned304
The cache-control and etag in the 1.1 specification should be preferred
What files should be cached?
There is no standard answer to this question, it depends entirely on the project requirements, but the homepage of the site must not be cached, otherwise the new content after version iteration will never be loaded, but general browsers will prohibit this sand sculpture behavior
over:)