HTTP If-Modified-Since引发的浏览器缓存汇总

在看Spring中HttpServlet的Service方法时,对于GET请求,代码逻辑如下:

if (method.equals(METHOD_GET)) {
            long lastModified = getLastModified(req);
            if (lastModified == -1) {
                // servlet doesn‘t support if-modified-since, no reason
                // to go through further expensive logic
                doGet(req, resp);
            } else {
                long ifModifiedSince;
                try {
                    ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
                } catch (IllegalArgumentException iae) {
                    // Invalid date header - proceed as if none was set
                    ifModifiedSince = -1;
                }
                if (ifModifiedSince < (lastModified / 1000 * 1000)) {
                    // If the servlet mod time is later, call doGet()
                    // Round down to the nearest second for a proper compare
                    // A ifModifiedSince of -1 will always be less
                    maybeSetLastModified(resp, lastModified);
                    doGet(req, resp);
                } else {
                    resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                }
            }

        }

其中涉及的关键信息是修改时间,这就涉及到浏览器数据缓存问题。以下对个缓存机制进行简单总结,可用于请求的优化。(本文中的图都摘自其他文章

Last-Modified和If-Modified-Since

当浏览器GET请求的时候,如果有If-Modified-Since,则会与当前服务器上相关资源最后一次修改时间进行对比,如果相同则返回304(资源可访问,但没修改),否则加载最新数据,浏览器再缓存起来。这样减少网络数据传输和服务器压力。

ETags和If-None-Match

根据修改时间判断文件是否被修改,如果一个网页被频繁更新,但实际内容并没有更新,依然会对服务器造成压力。引入了ETags和If-None-Match,其不同于Last-Modified和If-Modified-Since取决于修改时间,可以依赖其他属性,如资源的MD5等。当资源被更新,但实际内容没有更新,则会比较修改时间和ETags,如果ETags没变,则不更新数据资源。但查阅源码戴发现,目前底层实现上实现的是弱Etags,其由文本长度和修改时间组成,资源被更新后,ETags依然会更新。在AbstractResource中,代码如下:

  @Override
    public final String getETag() {
        if (weakETag == null) {
            synchronized (this) {
                if (weakETag == null) {
                    long contentLength = getContentLength();
                    long lastModified = getLastModified();
                    if ((contentLength >= 0) || (lastModified >= 0)) {
                        weakETag = "W/\"" + contentLength + "-" +
                                   lastModified + "\"";
                    }
                }
            }
        }
        return weakETag;
    }

Expires

添加Expires头能有效的利用浏览器的缓存能力来改善页面的性能,能在后续的页面中有效避免很多不必要的Http请求,WEB服务器使用Expires头来告诉Web客户端它可以使用一个组件的当前副本,直到指定的时间为止。例如:Expires:Thu,15 Apr  2010  20:00:00  GMT;  他告诉浏览器缓存有效性持续到2010年4月15日为止,在这个时间之内相同的请求使用缓存,这个时间之外使用http请求。Expires有一个非常大的缺陷,它使用一个固定的时间,要求服务器与客户端的时钟保持严格的同步,并且这一天到来后,服务器还得重新设定新的时间。

Cache-Control

HTTP1.1引入了Cathe-Control,它使用max-age指定组件被缓存多久(时间相对请求的时间),从请求开始在max-age时间内浏览器使用缓存,之外的使用请求,这样就可以消除Expires的限制。但有个缺点就是,用户不能第一时间拿到最新修改的文件。请求过程如下:

另外,gulp 给静态资源文件添加hash(md5)后缀防止缓存无效,能获取最新文件(这个需要进一步研究)

参考:

HTTP的请求头标签 If-Modified-Since

If-Modified-Since和If-None-Match

http://www.360doc.com/content/17/0721/17/41344223_673116604.shtml

前端性能优化 —— 添加Expires头

原文地址:https://www.cnblogs.com/shuimuzhushui/p/9689550.html

时间: 2024-10-01 07:19:10

HTTP If-Modified-Since引发的浏览器缓存汇总的相关文章

服务器与浏览器缓存协商控制机制的总结

http://www.ginano.net/browser-server-cache-control-rule 发表于2013 年 3 月 13 日由ginano 引子:昨天中文站出现了大量的用户投诉,投诉内容是运费发生变化,运费金额不正确.可是我们本地怎么测试都没有问题.但是考虑到问题唯一的可能是昨天的一个关于运费模版优化的项目引发的.因为,我昨天中午发布了一个style应用版本,发布时间是11点20分左右,运费模版优化项目的发布是在晚上9点钟左右.但是由于运费模版优化项目在正式发布阶段发现了

浏览器缓存机制浅析

非HTTP协议定义的缓存机制 浏览器缓存机制,其实主要就是HTTP协议定义的缓存机制(如: Expires: Cache-control等).但是也有非HTTP协议定义的缓存机制,如使用HTML Meta 标签,Web开发者可以在HTML页面的<head>节点中加入<meta>标签,代码如下: <META HTTP-EQUIV="Pragma" CONTENT="no-cache"> 上述代码的作用是告诉浏览器当前页面不被缓存,每

304和浏览器缓存

浏览器虽然发现了本地有该资源的缓存,但是不确定是否是最新的,于是想服务器询问,若服务器认为浏览器的缓存版本还可用,那么便会返回304. 浏览器缓存分为强缓存和协商缓存. 1.浏览器请求某资源,通过header判断是否强缓存,若是强缓存,则从本地直接获取缓存文件,不发请求到浏览器 2.若不是强缓存,发送请求到服务器,服务器通过一些request header确定是否是协商缓存,如果是,服务器将请求返回,但不返回资源,而是让客户端从本地缓存获取资源 3.强缓存和协商缓存,资源都是本地,只是强缓存不会

浏览器缓存策略

浏览器一般缓存图片.CSS.JS等静态文件,因为这些文件的更新频率相对来说比较低,合理利用浏览器的缓存对网站的性能提升有很大帮助.HTTP缓存分为两部分,分别是本地缓存和缓存协商,当本地缓存不生效时会启用缓存协商.HTTP缓存主要由HTTP协议的头(Header)信息来制定. 本地缓存 本地缓存是指当浏览器请求资源时,如果命中了浏览器本地的缓存资源,那么浏览器就不会发送真正请求给服务器.它的执行过程是:1. 第一次浏览器发送请求给服务器时,此时浏览器还没有本地缓存副本,服务器返回资源给浏览器,响

浏览器缓存知识小结及应用

阅读目录 1. 浏览器缓存基本认识 2. 强缓存的原理 3. 强缓存的管理 4. 强缓存的应用 5. 协商缓存的原理 6. 协商缓存的管理 7. 浏览器行为对缓存的影响 浏 览器缓存,也就是客户端缓存,既是网页性能优化里面静态资源相关优化的一大利器,也是无数web开发人员在工作过程不可避免的一大问题,所以在产品开发的 时候我们总是想办法避免缓存产生,而在产品发布之时又在想策略管理缓存提升网页的访问速度.了解浏览器的缓存命中原理,是开发web应用的基础,本文着眼 于此,学习浏览器缓存的相关知识,总

浏览器缓存机制(1)

浏览器缓存机制之一(经典缓存) 因为在接手的项目中用到过比较新的HTML5应用缓存,也用到了经典的缓存如设置max-age,Etag之类,而之前一直就是在用着没有去深究其中原理.周末天气不好,懒得出去了,正好找时间总结下. 1.关于浏览器缓存 记得去年看<HTTP权威指南>的时候,有一章是专门讲浏览器缓存的,一年时间过得太快,逝去的时光还真是如同人群中消失的好姑娘,眼看她嫁给别人.我这里把浏览器缓存分为经典的浏览器缓存(以下简称为经典缓存)和HTML5应用缓存这两类. 经典的浏览器缓存其实主要

解密浏览器缓存机制

浏览器缓存是节省用户流量,提升加载效率的常用方法:但同时它也会带来获取到历史脏数据等风险,今天我们就来详细介绍下浏览器缓存相关内容. 分类 浏览器的缓存主要包括两种缓存:强缓存.验证缓存. 1. 强缓存 强缓存是指浏览器不与服务器进行任何交互请求,直接将浏览器的缓存数据(包括缓存数据的 Response 头信息)返回给用户.这种缓存给用户的响应是最快的,但同时也是风险性较高的.因为该类缓存没有进行任何的校验即直接反馈给用户,是可能存在有历史的脏数据.当浏览器的请求出现同时以下两个现象时该次请求就

关于浏览器缓存

缓存分为2种: 1.  强缓存: 直接从本地缓存中取资源,不会和服务器通信,返回的http状态码是200(from cache): 2.  协商缓存:通过服务器来告知是否能用本地缓存.先和服务器通信,如果返回可以使用本地缓存的指示,再从本地缓存中取(服务器不会返回被请求资源,返回的状态码是403(Not Modified)):如果不可以使用本地缓存就会返回最新的资源: 浏览器发起第二次相同的请求时会先判断能不能使用强缓存,不行的话,再判断能不能使用协商缓存(如果没有设置强缓存,协商缓存也不会生效

深入了解浏览器缓存原理

浏览器缓存将文件保存在客户端,好的缓存策略可以减少对网络带宽的占用,可以提高访问速度,提高用户的体验,还可以减轻服务器的负担.因此我们有必要了解它的实现原理,用来提高网站的性能. 当一个客户端请求web服务器, 请求的内容可以从以下几个地方获取:服务器.浏览器缓存中或缓存服务器中.这取决于服务器端输出的页面信息.页面文件有三种缓存状态. 1.最新的:选择不缓存页面,每次请求时都从服务器获取最新的内容. 2.未过期的:在给定的时间内缓存,如果用户刷新或页面过期则去服务器请求,否则将读取本地的缓存,