在看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头

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

  1. web性能优化:详说浏览器缓存

    TOC 背景 浏览器的总流程图 一步一步说缓存 朴素的静态服务器 设置缓存超时时间 html5 Application Cache Last-Modified/If-Modified-Since Et ...

  2. nginx,控浏览器缓存,前端优化方案

    1,困惑 做web项目,对于开发者来说,一个最头痛的问题就是浏览器缓存,有缓存,js更改了,html更改了,发布服务器以后用户往往无法通过浏览器访问到最新的类容,需要用户主动去刷新页面, 因为一直做企 ...

  3. 浏览器缓存相关的Http头介绍:Expires,Cache-Control,Last-Modified,ETag

    转自:http://www.path8.net/tn/archives/2745 缓存对于web开发有重要作用,尤其是大负荷web系统开发中. 缓存分很多种:服务器缓存,第三方缓存,浏览器缓存等.其中 ...

  4. 浏览器缓存详解:expires,cache-control,last-modified,etag详细说明

    最近在对CDN进行优化,对浏览器缓存深入研究了一下,记录一下,方便后来者 画了一个草图: 每个状态的详细说明如下: 1.Last-Modified 在浏览器第一次请求某一个URL时,服务器端的返回状态 ...

  5. Nginx使用Expires增加浏览器缓存加速(转)

    转载自:Nginx使用Expires增加浏览器缓存加速 Nginx可以更改HTTP头部,这个是Web服务器必须的,当然Nginx更可以支持在HTTP头部中添加Expires等相关信息,增强浏览器缓存, ...

  6. HTTP请求中浏览器缓存

    本文导读:浏览器缓存机制,其实主要就是HTTP协议定义的缓存机制.客户端缓存是否需要是可以在服务端代码上控制的.那就是响应头.响应头告诉缓存器不要保留缓存,缓存器就不会缓存相应内容:如果请求信息是需要 ...

  7. 浏览器缓存相关http头

    近期看雅虎黄金34条,学习下优化站点性能的方法. 当中有一条:"为文件头指定Expires或Cache-Control",详细来说指对于静态内容:设置文件头过期时间Expires的 ...

  8. Nginx实践篇(2)- Nginx作为静态资源web服务 - 控制浏览器缓存、防盗链

    一.控制浏览器缓存 1. 浏览器缓存简介 浏览器缓存遵循HTTP协议定义的缓存机制(如:Expires;Cache-control等). 当浏览器无缓存时,请求响应流程 当浏览器有缓存时,请求响应流程 ...

  9. 【HTTP缓存】浏览器缓存理论知识

    时间:2016-12-12 17:51:30 作者: zhongxia 零.前言 这里主要写的是理论,具体实践的比较少,后期写一个实践教程,内容基本都是从参考文章里面抄过来的[看完文章,顺便写做下笔记 ...

随机推荐

  1. Java不同压缩算法的性能比较 程序猿 2015-01-21 本文将会对常用的几个压缩算法的

    Java不同压缩算法的性能比较 程序猿 2015-01-21 本文将会对常用的几个压缩算法的

  2. ElasticSearch报 EsThreadPoolExecutor[search, queue capacity = 1000, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@c0efba

    ElasticSearch报以下错误的解决办法: "type": "es_rejected_execution_exception", "reason ...

  3. Databases: MySQL tRIGger--chinese character-set php

    DELIMITER |create TRIGGER tr_calllog_insert after insert on messagescalllog for each row beginIF mes ...

  4. 场景服务只创建了 Service Difinition 和feature layer

    环境:物理机 pro1.4:虚拟机 (server + datastore + portal + adaptor) 10.4.1 发布场景服务,正常情况应portal中查看,应包含四部分内容:Serv ...

  5. 帝国cms调用缩略图和具体文章的方法

    我们在用帝国cms建站的时候经常会在首页或者分类页等调用一些文章,如果文章带有展示图也把图片调用出来.帝国cms调用缩略图和具体文章怎么操作呢?我们用帝国cms的灵动标签[e:loop],只要记住常用 ...

  6. python 全局变量与局部变量

    一.引用 使用到的全局变量只是作为引用,不在函数中修改它的值的话,不需要加global关键字.如: #! /usr/bin/python a = 1 b = [2, 3] def func(): if ...

  7. iOS 网易彩票-5设置模块二

    产品推荐 产品推荐使用的是UICollectionView控件,UICollectionView 和 UICollectionViewController 类是iOS6 新引进的API,用于展示集合视 ...

  8. Java之构造器和构造方法的使用和意义

    我总是要把构造器和方法混淆,后来发现, 方法,实际上,是需要用于执行java代码的,而构造器, 构造器,,,是一个类的实例!!(我的理解,构造器是一个对象) 为什么呢? 类的实例,我们需要用类来创建对 ...

  9. Django初级手册1-项目和应用的创建与简单的数据库操作

    创建项目 django-admin.py startproject mysite 1. 目录结构 mysite/ #项目的名称 manage.py #可通过命令和项目进行交互的文件 mysite/ # ...

  10. Understanding Convolutional Neural Networks for NLP

    When we hear about Convolutional Neural Network (CNNs), we typically think of Computer Vision. CNNs ...