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
分享到:
相关推荐
当客户端再次请求资源时,它会发送一个 `If-None-Match` 头,包含上次接收到的资源的ETag值。服务器会比较这个值与当前资源的ETag,如果两者匹配,同样会返回304 "Not Modified"响应。 相比于 `Last-Modified`,...
在HTTP协议中,Last-Modified和ETag两个头部字段是用来验证缓存是否过期,确保浏览器使用的缓存是最新的。 Last-Modified是一个HTTP头部字段,它包含了服务器上文件的最后修改日期和时间。当浏览器首次请求一个资源...
- Last-Modified和If-Modified-Since:根据资源最后修改时间判断是否需要重新获取。 8. **实战应用**: - 使用HttpClient库进行Java程序中的HTTP请求与响应处理。 - Spring MVC框架如何处理HTTP请求和构建响应。...
3. 缓存验证:若资源可能已更新,浏览器会发送一个带有If-None-Match或If-Modified-Since头的请求到服务器,服务器根据这些头信息判断资源是否改变,若无变化则返回304 Not Modified状态码,浏览器继续使用缓存;...
协商缓存的字段有 Last-Modified / If-Modified-Since 和 Etag / If-None-Match,其中 Etag / If-None-Match 的优先级比 Last-Modified / If-Modified-Since 高。 Last-Modified 字段,它的值是该资源文件在服务器...
- `If-None-Match`: 使用Etag值检查资源是否已更改。 2. **Response Headers**: - `Date`: 响应生成的日期和时间。 - `ETag`: 用于标识资源的特定版本,用于缓存验证。 - `Location`: 在重定向时指示新的URL。...
- Last-Modified和If-Modified-Since:通过资源的最后修改时间进行验证。 6. 安全与隐私: - HTTPS:HTTP加上SSL/TLS加密,确保通信安全。 - CORS:跨源资源共享,允许不同源之间的交互。 - Content-Security-...
此外,`ETag`(实体标签)也是验证缓存有效性的一个方法,它为每个资源生成一个唯一的标识符,当资源更新时,`ETag`也会变化,服务器通过比较`If-None-Match`头中的`ETag`值来判断是否需要提供新的内容。 在实际应用...
修改last-modified的HTTP规范,实现了last-modified , if-modified-since , etag , if-none-match 。概要Modified是根据构建的,并通过缓存支持对其进行修饰,因此,如果您熟悉请求,则几乎可以使用修改了。 var...
- **ETag/If-None-Match**: 提供了一个关于资源当前状态的标识符,用于判断资源是否发生变化。 #### 五、缓存相关的HTTP Header 1. **Cache-Control** - **概述**:Cache-Control是HTTP1.1中引入的新头部,用于...
在后续的请求中,如果资源未更改,中间件会检查客户端发送的If-None-Match头,如果Etag匹配,则返回304 Not Modified状态,而不是完整的响应体。 值得注意的是,Etag的性能优化效果取决于资源的更新频率。对于很少...
浏览器在请求中带上`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
- **示例**:`If-None-Match:“737060cd8c284d8af7ad3082f209582d”` ##### If-Range - **解释**:如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag。 - **示例**:`If-Range:“737060...
- **If-None-Match**: 如果资源的ETag不匹配给定值,则执行请求。 - **If-Unmodified-Since**: 如果资源自指定时间后未被修改,则执行请求。 - **Max-Forwards**: 对于转发请求,该字段限制了请求被转发的最大次数。...
强缓存通过这些头部直接决定是否使用缓存,而协商缓存则通过`Last-Modified`/`If-Modified-Since`或`ETag`/`If-None-Match`与服务器通信来验证资源是否更新。Service Worker提供了更细粒度的缓存控制,支持离线应用...
3. **重新验证**: 如果资源已经过期,浏览器将向服务器发送一个新的请求,附带`If-Modified-Since` 或 `If-None-Match` 头部,询问资源是否已被修改。如果资源未更改,则服务器返回304 Not Modified状态码,表明可以...
协商缓存通常涉及Last-Modified/If-Modified-Since和Etag/If-None-Match两个字段。Last-Modified是服务器返回资源的最后修改时间,If-Modified-Since是客户端再次请求时携带的Last-Modified值,用来告诉服务器资源的...
3. **`Last-Modified`与`If-Modified-Since`**: 类似于`ETag`,`Last-Modified`头表示资源的最后修改时间。如果客户端在下次请求时提供`If-Modified-Since`头,服务器会比较这个时间,如果资源未修改,则返回`304 ...