*用于备忘
关于缓存几个重要的属性
Expires,Cache-control,
Last-Modified/If-Modified-Since,Etag/If-None-Match
Expires策略
Expires是RFC 2616(HTTP/1.0)协议中和网页缓存相关字段。用来控制缓存的失效日期,声明了一个网页或URL地址不再被浏览器的时间,一旦超过了这个时间,浏览器都应该联系原始服务器。要注意的是,HTTP/1.0有一个功能比较弱的缓存控制机制:Pragma,使用HTTP/1.0的缓存将忽略Expires和Cache-Control头。
Cache-control策略(常用)
Cache-Control与Expires的作用一致,都是指明当前资源的有效期,网页的缓存是由消息头中的“Cache-control”来控制的,常见的取值有private、no-cache、max-age、must-revalidate等,默认为private。
Expires策略
Expires是RFC 2616(HTTP/1.0)协议中和网页缓存相关字段。用来控制缓存的失效日期,声明了一个网页或URL地址不再被浏览器的时间,一旦超过了这个时间,浏览器都应该联系原始服务器。要注意的是,HTTP/1.0有一个功能比较弱的缓存控制机制:Pragma,使用HTTP/1.0的缓存将忽略Expires和Cache-Control头。
Cache-control策略(常用)
Cache-Control与Expires的作用一致,都是指明当前资源的有效期,网页的缓存是由消息头中的“Cache-control”来控制的,常见的取值有private、no-cache、max-age、must-revalidate等,默认为private。
Cache-directive | 说明 |
---|---|
public | 所有内容都将被缓存 |
private | 内容只缓存到私有缓存中 |
no-cache | 所有内容都不会被缓存 |
no-store | 所有内容都不会被缓存到缓存或 Internet 临时文件中 |
must-revalidation/proxy-revalidation | 如果缓存的内容失效,请求必须发送到服务器/代理以进行重新验证 |
max-age=xxx (xxx is numeric) | 缓存的内容将在 xxx 秒后失效, 这个选项只在HTTP 1.1可用, 并如果和Last-Modified一起使用时, 优先级较高 |
Last-Modified/If-Modified-Since
(要配合Cache-Control使用)
Last-Modified:标示这个响应资源的最后修改时间。web服务器在响应请求时,告诉浏览器资源的最后修改时间。
If-Modified-Since:当资源过期时(使用Cache-Control标识的max-age),发现资源具有Last-Modified声明,则再次向web服务器请求时带上头 If-Modified-Since,表示请求时间。web服务器收到请求后发现有头If-Modified-Since 则与被请求资源的最后修改时间进行比对。若最后修改时间较新,说明资源又被改动过,则响应整片资源内容(写在响应消息包体内),HTTP 200;若最后修改时间较旧,说明资源无新修改,则响应HTTP 304
(无需包体,节省浏览),告知浏览器继续使用所保存的cache。
Etag策略(优先级最高)
Etag:web服务器响应请求时,告诉浏览器当前资源在服务器的唯一标识(生成规则由服务器决定)。Apache中,ETag的值,默认是对文件的索引节(INode),大小(Size)和最后修改时间(MTime)进行Hash后得到的。
ETags和GET请求的“If-None-Match”头一起使用,这样可利用客户端(例如浏览器)的缓存。因为服务器首先产生ETag,服务器可在稍后使用它来判断页面是否已经被修改。本质上,客户端通过将该记号传回服务器要求服务器验证其(客户端)缓存。
其过程如下:
客户端请求一个页面(A)。 服务器返回页面A,并在给A加上一个ETag。 客户端展现该页面,并将页面连同ETag一起缓存。 客户再次请求页面A,并将上次请求时服务器返回的ETag一起传递给服务器。 服务器检查该ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304(未修改——Not Modified)和一个空的响应体。
Cache-Control的简单使用
不可取的方法
通过Filter实现
ResponseHeaderFilter.java
然后在web.xml中配置过滤器
js和css资源后面加上版本号,项目更新发布新版本修改版本号即可,避免有时候客服端资源不更新问题
<script type="text/javascript" src="js/test.js?v=0.1"></script>
客户端请求一个页面(A)。 服务器返回页面A,并在给A加上一个ETag。 客户端展现该页面,并将页面连同ETag一起缓存。 客户再次请求页面A,并将上次请求时服务器返回的ETag一起传递给服务器。 服务器检查该ETag,并判断出该页面自上次客户端请求之后还未被修改,直接返回响应304(未修改——Not Modified)和一个空的响应体。
Cache-Control的简单使用
不可取的方法
<meta http-equiv="Cache-Control" content="max-age=7200" />
<meta http-equiv="Expires" content="Mon, 20 Jul 2009 23:00:00 GMT" />
上述设置仅为举例,实际使用其一即可。这样写的话仅对该网页有效,对网页中的图片或其他请求无效,并不会做任何cache。
通过Filter实现
ResponseHeaderFilter.java
package com.filter;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
public class ResponseHeaderFilter implements Filter {
FilterConfig fc;
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) res;
// set the provided HTTP response parameters
for (Enumeration e = fc.getInitParameterNames(); e.hasMoreElements();) {
String headerName = (String) e.nextElement();
response.addHeader(headerName, fc.getInitParameter(headerName));
}
// pass the request/response on
chain.doFilter(req, response);
}
public void init(FilterConfig filterConfig) {
this.fc = filterConfig;
}
public void destroy() {
this.fc = null;
}
}
然后在web.xml中配置过滤器
<filter>
<filter-name>NoCache</filter-name>
<filter-class>com.filter.ResponseHeaderFilter</filter-class>
<init-param>
<param-name>Cache-Control</param-name>
<param-value>no-cache, must-revalidate</param-value>
</init-param>
</filter>
<filter>
<filter-name>Cache</filter-name>
<filter-class>com.filter.ResponseHeaderFilter</filter-class>
<init-param>
<param-name>Cache-Control</param-name>
<param-value>max-age=999999, public</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>NoCache</filter-name>
<url-pattern>*.action</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Cache</filter-name>
<url-pattern>/images/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Cache</filter-name>
<url-pattern>*.js</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>Cache</filter-name>
<url-pattern>*.css</url-pattern>
</filter-mapping>
对于action请求页面不需要设置缓存,页面其他资源增加缓存。
js和css资源后面加上版本号,项目更新发布新版本修改版本号即可,避免有时候客服端资源不更新问题
<script type="text/javascript" src="js/test.js?v=0.1"></script>