Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HTTP缓存 #20

Closed
xwchris opened this issue Jul 8, 2018 · 0 comments
Closed

HTTP缓存 #20

xwchris opened this issue Jul 8, 2018 · 0 comments
Labels

Comments

@xwchris
Copy link
Owner

xwchris commented Jul 8, 2018

缓存相关头部

  1. Expires 响应头,代表资源过期时间
  2. Cache-Control 请求头/响应头,缓存控制字段,精确控制缓存策略
  3. If-Modified-Since 请求头,资源最近修改时间,由浏览器告诉服务器
  4. Last-Modified 响应头,资源最近修改时间,由服务器告诉浏览器
  5. Etag 响应头,资源标识,由服务器告诉浏览器
  6. If-None-Match 请求头,缓存资源标识,由浏览器告诉服务器

字段详解

假设现在不看请求头的情况下要浏览器要缓存一个文件,读相同的文件的时候直接读取本地的缓存,这样减少了请求,但是会造成服务器资源过期也不更新的情况,所以这时候引入响应头Expires

Expires

响应头Expires是由服务器告知浏览器的资源过期时间,在资源过期之前,浏览器可以一直使用本地的缓存,过期之后,浏览器可以再次请求服务器。它的值是GMT格式的标准时间,如Fri, 01 Jan 1990 00:00:00 GMT

虽然服务器端可以设置资源过期时间,但是服务器端并无法精确的知道资源什么过期,因此存在浏览器中Expires过期时间到了,但是服务器资源并没有更新的情况,这个时候请求一个相同的文件影响带宽。为了解决这个问题,在服务器响应头中增加了Last-modified字段。

Last-Modified & If-Modified-Since

响应头Last-Modified和请求头If-Modified-Since配合使用,为了解决上述问题,服务器端使用Last-Modified返回资源最新一次的修改时间。当浏览器资源过期的再次请求服务器的时候,带上If-Modified-Since请求头,该请求头与上次请求Last-Modified的值保持一致。如果服务器端检测到If-Modified-Since的值与目前资源的修改时间一致,则直接返回304告诉浏览器资源没有更改,可以继续使用缓存。

到了这里还是存在问题,如果资源的修改时间确实变化了,但是文件内容没有变,再次请求相同的文件,同样是一种浪费带宽的表现,所以引出下一个概念Etag

Etag && If-None-Match

Etag是根据文件内容计算出的唯一标识符,当Etag变化时,说明文件确实被修改了。与Etag配合使用的是If-None-MatchEtag是服务器响应头,If-None-Match是浏览器请求头。每次请求如果有If-None-Match那么会忽略If-Modified-since

Catch-Control

一种新的缓存过期控制方案,它可以甚至相对时间等很多属性,如果存在Catch-Control则忽略掉ExpiresCatch-Control的值包括:

  1. max-age:可以设定相对时间,时间为s
  2. public: 资源允许被中间代理服务器缓存
  3. private: 资源不允许被中间代理服务器缓存
  4. no-cache: 浏览器不做缓存检查,服务器检查文件,如果没变返回304
  5. no-store: 浏览器和中间代理服务器都不缓存,服务器不检查文件,直接返回资源
  6. must-revalidate:可以缓存,但是使用之前必须先向源服务器确认。
  7. proxy-revalidate:要求缓存服务器针对缓存资源向源服务器进行确认。
  8. s-maxage:缓存服务器对资源缓存的最大时间。

实际开发中的缓存方案

http缓存固然很好,但是由于http缓存的存在,浏览器无法主动感知资源的变化。会造成我们资源更新了,但是浏览器没有刷新的情况。实际情况中可以不给html文件做缓存,每次都请求最新的文件,至于资源改变后,我们可以用一个独特的MD5值来命名文件,引入html中,例如bundle.xxxx.name这种命名,这样每次都会引用最新的资源,同时这样可以做到服务器热更新。

@xwchris xwchris added the bug Something isn't working label Jul 8, 2018
@xwchris xwchris closed this as completed Jul 8, 2018
@xwchris xwchris reopened this Jul 9, 2018
@xwchris xwchris changed the title Found a bug 技术小记-HTTP缓存 Jul 9, 2018
@xwchris xwchris added http and removed bug Something isn't working labels Jul 9, 2018
@xwchris xwchris changed the title 技术小记-HTTP缓存 HTTP缓存 Oct 15, 2019
@xwchris xwchris closed this as completed Nov 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant