浏览器缓存

Posted zousc

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浏览器缓存相关的知识,希望对你有一定的参考价值。

前言  

  浏览器缓存又叫客户端缓存,存储在客户端的缓存,由浏览器控制,关于存储的策略由响应头(Response Header)规定,主要的响应头标记是Cache-Contro、Etag、Last-Modified.

生效范围:

  仅对当前浏览器生效。

实现方式:

  使用HTTP Header

更新策略:

  Time-ETag-Version 如:max-age:60       设定缓存60秒 xxx.js?version=v1  xxx.css?version=v1  改变css,js请求地址即可重新请求css,js文件,也就是只要改变version即可

 

客户端缓存相关

  • Etag是个MD5摘,由服务器发送给客户端的一串字符,用来资源是否发生改变。
  • If-None-Match是在Etag存在的情况下请求服务器时发送给服务器用来校验资源的哈希值,当客户端发送的摘要与服务器的不同则重新请求,返回200,相同则返回304使用本地存储的资源;如:If-None-Match: "3f80f-1b6-3e1cb03b",3f80f-1b6-3e1cb03b是Etag
  • Last-Modified是资源最后修改时间,用来与服务器对比检验资源是否发生改变。
  • If-Modified-Since是在Last-Modified存在时,将Last-Modified发送给服务器,服务器端的资源最后修改时间与浏览器发送过来的对比,相同返回304使用本地存储的资源,否则返回200重新请求资源.

 

Cache-Contro

  • no-store:彻底禁用缓冲,所有内容都不会被缓存到缓存或临时文件中,如果已经存在还是会加载。
  • no-cache:在浏览器使用缓存前,会往返对比ETag,如果ETag没变,返回304,则使用缓存,no-cache不代表不存储缓存,只是存储而不直接使用,必须先和服务器做对比然后才决定要不要使用,没有直接使用磁盘缓存快,但是比在服务器请求资源快。 public 所有内容都将被缓存(客户端和代理服务器都可缓存)。
  • private:内容只缓存到私有缓存中(仅客户端可以缓存,代理服务器不可缓存)。
  • max-age:缓存的内容将在 xxx 秒后失效,这个选项只在HTTP1.1可用,并如果和Last-Modified一起使用时,优先级较高。

 

客户端缓存流程

  先上一张缓存流程图

        技术图片

  图解:当客户端发起请求,第一步会先检查缓存是否过期,没过期直接读取缓存(一些资源浏览器都会存储在内存中,第二次请求时返回200 memory cache),当内存中存储没了会使用磁盘中的缓存文件返回200(disk cache)。如果已过期浏览器将向判断是否存在Etag,存在的话服务器发送If-None-Match:第一次请求获得的Etag,服务器拿到该Etag对比是否改变,如果没变如果资源为改变返回304HTTP状态码,否则从新请求返回200HTTP状态码。当不存在Etag时,查看是否存在Last-Modified(最后修改时间),存在的话走向web服务器请求带If-Modfied-Since路线,If-Modified-Since把浏览器缓存页面的最后修改时间发送给服务器做对比,如果时间一致则返回304HTTP状态码,直接从本地获取资源,否则返回200HTTP状态码重新请求。如果Etag不存在,Last-Modified不存在直接向服务器发送请求。

  使用缓存时,状态码会返回200或者304,当返回200时Size为disk cache或者memory cache,都是在客户端存储着,所以并没有像服务器请求,直接获取客户端缓存; 当服务端和客户端都存在缓存,客户端缓存过期后再去请求服务器会带Etag和Last-Modified,如果资源没有改变返回304

 

示例

  在.net core3.1中使用:

  MVC控制器使用缓存,使用特性或者在响应头中使用cache-control

技术图片
 [ResponseCache(Duration = 7200, Location = ResponseCacheLocation.Any)]
    public class testController : Controller
    {
        public IActionResult Index()
        {
            var time = DateTime.Now.ToString();
            ViewBag.Current = time;
            //base.HttpContext.Response.Headers["Cache-control"] = "no-cache";
            return View();
        }
    }
View Code

 

  Startup中制定静态文件缓存策略

技术图片
app.UseStaticFiles(new StaticFileOptions
            {
                FileProvider=new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(),@"wwwroot")),
                OnPrepareResponse = ctx => {
                    //ctx.Context.Response.Headers[HeaderNames.CacheControl] = "no-cache";
                    ctx.Context.Response.Headers[HeaderNames.CacheControl] = "no-cache, max-age=0, must-revalidate";
                }
            });
View Code

  注意:由于浏览器会自动缓存静态文件,所以不好测试;不同的浏览器不同的缓存流程,缓存也不一样,只要请求到了就会自动缓存,第二次请求如果在同一个tab会返回200(memory cache),这是由于在内存缓存中加载的结果;如果在不同tab那么memory cache不存在,于是会从磁盘读取缓存,返回200(disk cache);当设置的响应cache-control为no-cache时正常情况下第二次请求会返回304,按照上图中流程,走的是Etag路线=》服务器决策=》304;

 

网络请求

  第一次请求与第二次请求结果

  技术图片

 

  第一次网络请求,所有资源都是从服务器请求过来的

技术图片技术图片

  第二次网络请求,所有资源都被缓存在磁盘,如果在同一个页面请求时(memory cache),否则如下图

技术图片

  通过使用不同的cache-control可以控制缓存策略,按照自己所需的实际情况配置。

 

 

 

 

 

 

技术图片

 

以上是关于浏览器缓存的主要内容,如果未能解决你的问题,请参考以下文章

在每个用户的Rails中使用片段缓存

Android获取各个应用程序的缓存文件代码小片段(使用AIDL)

用手机UC浏览器缓存视频为啥是很多个小文件?怎么让它合成一个视频文件?

如何缓存片段视图

phalcon: 缓存片段,文件缓存,memcache缓存

文件缓存(模板缓存)