HTTP/1.1缓存

什么是HTTP缓存

HTTP缓存主要是用来缓存一些资源在浏览器,如果使用了HTTP缓存,那么下次请求资源的时候就不会响应资源了,而是返回状态码304,告知使用本地缓存。

HTTP缓存实验

1. 编写请求页面

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    </head>
    <body>
        <img src="images/head.png" />
        <a href="page.html">重新访问page页</a>
    </body>
</html>

2. 第一次请求响应报文

image

说明:
第一次浏览器发送请求到服务器,发送请求头 Cache-Control字段为no-cache,no-cache会将数据缓存到本地,但是下次会强制向服务器发起验证。服务器向客户端返回最后修改时间Last-modified和服务器资源标识ETag(服务器会为每个资源都分配一个ETag,作为唯一标识,如果资源发生一些细微修改,就会加上W/".......")。因为第一次请求没有访问浏览器的本地缓存,所以返回响应状态码为200,然后将当前的资源缓存到浏览器本地

3. 第二次请求响应报文

image

说明:
第二次浏览器发送请求到服务器,不是直接去请求资源,而是验证当前浏览器的缓存是否有效。服务器主要比对的请求头字段是If-Modified-Since判断最后修改时间是否匹配和请求头字段If-None-Match指定当前的资源
如果发现字段If-None-Match指定的资源判断字段If-Modified-Since时间大于最后修改时间,那么就从服务器上将资源重新返回响应码为200,如果小于等于最后修改时间,说明资源没有发生修改,那么就直接使用浏览器本地缓存,返回响应码为304

请求头Cache-Control

image

springmvc源码中HTTP缓存的设计代码

// 检查是否修改过请求,通过ETAG确定资源,lastmodifiedtime来确定修改时间
@Override
public boolean checkNotModified(long lastModifiedTimestamp) {
    if (lastModifiedTimestamp >= 0 && !this.notModified &&
            (this.response == null || !this.response.containsHeader(HEADER_LAST_MODIFIED))) {
        long ifModifiedSince = getRequest().getDateHeader(HEADER_IF_MODIFIED_SINCE);
        this.notModified = (ifModifiedSince >= (lastModifiedTimestamp / 1000 * 1000));
        if (this.response != null) {
            if (this.notModified && METHOD_GET.equals(getRequest().getMethod())) {
                this.response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
            }
            else {
                this.response.setDateHeader(HEADER_LAST_MODIFIED, lastModifiedTimestamp);
            }
        }
    }
    return this.notModified;
}   
posted @ 2023-07-27 15:53  sunpeiyu  阅读(27)  评论(0编辑  收藏  举报