ETag和Last-Modified用法上的区别是:ETag必须由开发人员来使用,而Last-Modified服务器会自动判断。也就是说服务器自己能够获取文件的"Last-Modified"并和"If-Modify-Since"进行对比,进而决定发送什么样的响应。而ETag则必须由开发人员自己来和"If-None-Match"进行比较判断。
加上ETag一个用途是,假如文件被编辑了,但实际上内容并没有变化,此时可以指定ETag的值不变,这样它和浏览器发送过来的"If-None-Match"的值就相等了,进而可以指定响应为304,即未发生改变。如果不加ETag这个功能,则浏览器会发送200响应。
具体演示代码晚上再写,第一次研究技术熬到这么晚,困了。
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
ServletException {
HttpServletRequest servletRequest = (HttpServletRequest) req;
HttpServletResponse servletResponse = (HttpServletResponse) res;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ETagResponseWrapper wrappedResponse = new ETagResponseWrapper(servletResponse, baos);
chain.doFilter(servletRequest, wrappedResponse);
byte[] bytes = baos.toByteArray();
String token = '"' + EtagComputeUtils.getMd5Digest(bytes) + '"';
servletResponse.setHeader("ETag", token);
// servletResponse.setHeader("Cache-Control", "max-age=5"); //
servletResponse.setHeader("Cache-Control", "no-cache"); //
String previousToken = servletRequest.getHeader("If-None-Match");
if (previousToken != null && previousToken.equals(token)) {
logger.debug("ETag match: returning 304 Not Modified");
servletResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
} else {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MILLISECOND, 0);
Date lastModified = cal.getTime();
servletResponse.setDateHeader("Last-Modified", lastModified.getTime());
logger.debug("Writing body content");
servletResponse.setContentLength(bytes.length);
ServletOutputStream sos = servletResponse.getOutputStream();
sos.write(bytes);
sos.flush();
sos.close();
}
}
请注意这个,有它没它差别很大:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ETagResponseWrapper wrappedResponse = new ETagResponseWrapper(servletResponse, baos);
chain.doFilter(servletRequest, wrappedResponse);
如果不使用wrappedResponse而是原始的servletResponse,则在Ctrl+f5的情形下无论是ETag还是response设置都会消失,也就是说响应信息将不由本程序控制,而上述代码就可以解决这个问题。
ETagResponseWrapper,ETagResponseStream类代码见附件。
参考资料:
infoq,etag
分享到:
相关推荐
GET /pic/201408/102.jpg HTTP/1.1 Host: www.jb51.net Connection: keep-alive Cache-Control: no-cache Accept: image/webp,*/*;q=0.8 Pragma: no-cache User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/...
修改last-modified的HTTP规范,实现了last-modified , if-modified-since , etag , if-none-match 。概要Modified是根据构建的,并通过缓存支持对其进行修饰,因此,如果您熟悉请求,则几乎可以使用修改了。 var...
浏览器缓存机制、Expires策略(http1.0)和Cache-control策略(http1.1)、Last-Modified/If-Modified-Since、ETag/If-None-Match
精品软件工具--系统工具:手机检测,缓存清理,进程释放与软件管理
| 权限控制:SpringSecurity | | 工作流引擎:Activiti | | 前端技术:vue-admin-template + Node.js + Npm + Vue + ElementUI + Axios | | 微信公众号:公众号菜单 + 微信授权登录 + 消息推送 | 三、项目模块 - ...
---cache:网站缓存目录 ---libs:网站系统文件目录 jsphp:jsphp框架目录 ---tpl:框架模板目录 ---libs:框架系统文件目录 ---driver:数据库操作类 ---template:模板解析类 public:静态html目录 index....
强缓存通过这些头部直接决定是否使用缓存,而协商缓存则通过`Last-Modified`/`If-Modified-Since`或`ETag`/`If-None-Match`与服务器通信来验证资源是否更新。Service Worker提供了更细粒度的缓存控制,支持离线应用...
权限控制模型 404页面 建立模块主入口 bootstrap 缓存静态文件 安全性模块(XSS cookies验证) 官网依赖模块包括: "koa": "",//koa核心模块 "koa-route": "",//路由模块 "koa-static": "",//静态...
目录结构:app:网站系统目录 ---common:网站配置目录 ---tpl:网站模板目录 ---logs:网站日志目录 ---cache:网站缓存目录 ---libs:网站系统文件目录jsphp:jsphp框架目录 ---tpl:框架模板目录 ---libs...
26 If-None-Match 27 27 If-Range 28 28 If-Unmodified-Since 28 29 Last-Modified 29 30 Location 29 31 Max-Forwards 29 32 Pragma 30 33 Proxy-Authenticate 30 34 Proxy-Authorization 31 35 Range 31 1字节范围...
- 缓存:Redis或本地缓存 #### 后端 - 基础框架:Spring Boot 2.3.1.RELEASE - 持久层框架:Mybatis-plus_3.3.2 - 安全框架:Apache Shiro 1.5.3,Jwt_3.10.3 - 数据库连接池:阿里巴巴Druid 1.1.17 - 缓存...
- chapter4-2-3:[对log4j进行多环境不同日志级别的控制](http://blog.didispace.com/springbootlog4jmuilt/) - chapter4-2-4:[使用AOP统一处理Web请求日志](http://blog.didispace.com/springbootaoplog/) - ...
缓存ETag标头,并通过If-None-Match标头将它们发送回服务器。 使用灵活的缓存配置来缓存响应数据。 支持$cacheFactory , sessionStorage和localStorage开箱即localStorage缓存。 轻松于其他第三方缓存服务。 与...
:books: :satellite_antenna: HTTP Apollo链接,具有由数据加载器提供的批处理和缓存。 理念 一个Apollo链接,可同时在Node和Browser中批量处理请求。 您可能会问与什么区别。 该库没有像apollo-link-batch-http...
对fetch / XMLHttpRequest和ImageView进行本机http缓存控制 的iOS 安卓安装$ npm install react-native-http-cache2 --saveiOS:在您的XCode项目中进行链接从node_modules/react-native-http-cache2/ios文件夹中链接...
HTTP 状态码 2xx:表示报文被成功接收 3xx:表示重定向,客户端...If-Modified-Since 和 Last-Modified:基于时间实现,在发现请求到的资源携带 Last-Modified,那 么在下一次请求时,会将其值携带在If-Modified-Since
Modified-Since / If-None-Match) 各种支持缓存控制:公共,专用,最大使用期限,s-最大使用期限,必须重新验证和代理重新验证。 可移植:100%Ruby /可与任何支持Rack的框架一起使用磁盘,内存缓存和堆内存存储...
禁用固定缓存 固定插件以禁用客户端缓存 介绍 受启发, fastify-disablecache插件设置以下响应标头和值以禁用客户端缓存: Surrogate-Control: no-store Cache-Control: no-store, no-cache, must-revalidate, ...