`
hyj1254
  • 浏览: 339841 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

http协议-缓存控制:etag If-None-Match / Last-Modified If-Modified-Since

 
阅读更多
   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
0
1
分享到:
评论

相关推荐

    Caching HTTP Headers, Last-Modified and ETag

    当客户端再次请求资源时,它会发送一个 `If-None-Match` 头,包含上次接收到的资源的ETag值。服务器会比较这个值与当前资源的ETag,如果两者匹配,同样会返回304 "Not Modified"响应。 相比于 `Last-Modified`,...

    HTTP缓存头Last-Modified和ETag介绍

    在HTTP协议中,Last-Modified和ETag两个头部字段是用来验证缓存是否过期,确保浏览器使用的缓存是最新的。 Last-Modified是一个HTTP头部字段,它包含了服务器上文件的最后修改日期和时间。当浏览器首次请求一个资源...

    Java Web_HTTP协议详解第二讲

    - Last-Modified和If-Modified-Since:根据资源最后修改时间判断是否需要重新获取。 8. **实战应用**: - 使用HttpClient库进行Java程序中的HTTP请求与响应处理。 - Spring MVC框架如何处理HTTP请求和构建响应。...

    web浏览器-缓存详解

    3. 缓存验证:若资源可能已更新,浏览器会发送一个带有If-None-Match或If-Modified-Since头的请求到服务器,服务器根据这些头信息判断资源是否改变,若无变化则返回304 Not Modified状态码,浏览器继续使用缓存;...

    最新大厂前端面试题-笔试题2.doc

    协商缓存的字段有 Last-Modified / If-Modified-Since 和 Etag / If-None-Match,其中 Etag / If-None-Match 的优先级比 Last-Modified / If-Modified-Since 高。 Last-Modified 字段,它的值是该资源文件在服务器...

    HTTP_Header_详解.doc

    - `If-None-Match`: 使用Etag值检查资源是否已更改。 2. **Response Headers**: - `Date`: 响应生成的日期和时间。 - `ETag`: 用于标识资源的特定版本,用于缓存验证。 - `Location`: 在重定向时指示新的URL。...

    http.zip_规范的包文

    - Last-Modified和If-Modified-Since:通过资源的最后修改时间进行验证。 6. 安全与隐私: - HTTPS:HTTP加上SSL/TLS加密,确保通信安全。 - CORS:跨源资源共享,允许不同源之间的交互。 - Content-Security-...

    初探浏览器缓存实现原理-提高性能

    此外,`ETag`(实体标签)也是验证缓存有效性的一个方法,它为每个资源生成一个唯一的标识符,当资源更新时,`ETag`也会变化,服务器通过比较`If-None-Match`头中的`ETag`值来判断是否需要提供新的内容。 在实际应用...

    node-modified:修改后是一个简单的请求客户端来处理http本地缓存

    修改last-modified的HTTP规范,实现了last-modified , if-modified-since , etag , if-none-match 。概要Modified是根据构建的,并通过缓存支持对其进行修饰,因此,如果您熟悉请求,则几乎可以使用修改了。 var...

    浏览器之HTTP缓存的那些事

    - **ETag/If-None-Match**: 提供了一个关于资源当前状态的标识符,用于判断资源是否发生变化。 #### 五、缓存相关的HTTP Header 1. **Cache-Control** - **概述**:Cache-Control是HTTP1.1中引入的新头部,用于...

    Laravel开发-laravel-etag-middleware

    在后续的请求中,如果资源未更改,中间件会检查客户端发送的If-None-Match头,如果Etag匹配,则返回304 Not Modified状态,而不是完整的响应体。 值得注意的是,Etag的性能优化效果取决于资源的更新频率。对于很少...

    浏览器HTTP缓存运行机制流程图.zip

    浏览器在请求中带上`If-None-Match`头,包含上次获取的`ETag`。服务器比较这个`ETag`,如果匹配则返回304 Not Modified,浏览器使用缓存;不匹配则返回新的资源。 - `Last-Modified`: 类似于`ETag`,记录资源的最后...

    浏览器缓存机制

    浏览器缓存机制、Expires策略(http1.0)和Cache-control策略(http1.1)、Last-Modified/If-Modified-Since、ETag/If-None-Match

    http协议 heat response.docx

    - **示例**:`If-None-Match:“737060cd8c284d8af7ad3082f209582d”` ##### If-Range - **解释**:如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag。 - **示例**:`If-Range:“737060...

    tcp/ip-HTTP-Header-消息报头

    - **If-None-Match**: 如果资源的ETag不匹配给定值,则执行请求。 - **If-Unmodified-Since**: 如果资源自指定时间后未被修改,则执行请求。 - **Max-Forwards**: 对于转发请求,该字段限制了请求被转发的最大次数。...

    浏览器缓存技术介绍以及优化建议

    强缓存通过这些头部直接决定是否使用缓存,而协商缓存则通过`Last-Modified`/`If-Modified-Since`或`ETag`/`If-None-Match`与服务器通信来验证资源是否更新。Service Worker提供了更细粒度的缓存控制,支持离线应用...

    浏览器HTTP缓存机制

    3. **重新验证**: 如果资源已经过期,浏览器将向服务器发送一个新的请求,附带`If-Modified-Since` 或 `If-None-Match` 头部,询问资源是否已被修改。如果资源未更改,则服务器返回304 Not Modified状态码,表明可以...

    浏览器的缓存机制1

    协商缓存通常涉及Last-Modified/If-Modified-Since和Etag/If-None-Match两个字段。Last-Modified是服务器返回资源的最后修改时间,If-Modified-Since是客户端再次请求时携带的Last-Modified值,用来告诉服务器资源的...

    HTTP cache trainning

    3. **`Last-Modified`与`If-Modified-Since`**: 类似于`ETag`,`Last-Modified`头表示资源的最后修改时间。如果客户端在下次请求时提供`If-Modified-Since`头,服务器会比较这个时间,如果资源未修改,则返回`304 ...

Global site tag (gtag.js) - Google Analytics