http緩存之304 last-modified,cache-control:max-age,Etag等


因最近客戶端慢的問題,系統分析了下http協議緩存問題。本文主要記錄總結http緩存相關知識。

1. 討論涉及的要點

訪問返回類

> 訪問返回200 OK

> 訪問返回200 (from memory cache)

> 訪問返回200 (from disk cache)

> 訪問返回304 Not Modified

頭設置類

> Cache-Control: max-age=604800

> Expires: Thu, 05 Jan 2017 12:24:24 GMT

2. 測試環境1

機器A作為客戶端,IP: 10.0.0.2     chrome  版本 55.0.2883.87 m

機器B作為服務斷, IP: 10.0.0.102  nginx 1.1.19 ubuntu 12.04

3. 測試1 nginx直接作為后端服務器

1) 修改nginx的配置文件

location / {
        # First attempt to serve request as file, then
        # as directory, then fall back to index.html
        try_files $uri $uri/ /index.html;
        # Uncomment to enable naxsi on this location
        # include /etc/nginx/naxsi.rules
                                expires 7d;
    }

增加了expires 7d;

2) 修改index.html

<html>
<head>
<title>Welcome to nginx!</title>
<script type="text/javascript" src="1.js"></script>
</head>
<body bgcolor="white" text="black">
<center><h1>Welcome to nginx!123456</h1></center>
<a href="1.txt">1.txt</a>
</body>
</html>

增加一個引入js 1.js

增加一個超鏈接1.tx

4.  第一次訪問http://10.0.0.102/index.html (記得清理瀏覽器緩存)

bh1tk32v.pld

uxol2rrt.ua3

上圖為index.html請求包

ojxmnga3.g41

上圖為index.html響應包

w1kqhjx2.ied

z4dcet4v.k2y

上圖為1.js請求包

avmtuhuw.nji

上圖為1.js響應包

這是index.html和1.js都返回200 ok的情況

5. 第二次訪問http://10.0.0.102/index.html 在地址欄敲回車鍵

tyfuxsv0.rkx

quopghfd.ioi

上圖為index.html請求包

3vch334v.e1b

上圖為index.html響應包,此時 回 304 Not Modified ,並且服務器僅僅是回了狀態碼,沒有將index.html數據寫回客戶端

 

kkryocuo.jty

從整個抓包來看,沒有看到1.js的請求包,證明此時針對1.js這個文件 連http請求都沒有發

再通過那個超鏈接做實驗發現和1.js一樣的結論,第一次回200 OK   第二次之后就會200  from xxx cache

cache有memory和disk之分,這個很好理解。

 

在已經緩存了的情況下:

在地址欄敲回車,是回304 。  被別人引用或者點擊超鏈接時,回 200  form xxx cache

參考 http://guojianxiang.com/posts/2015-09-01-About_HttpStatus200_FromCache_And_304_NotModified.html 彎路2

6. 關於etag

nginx默認不支持etag, 可以使用插件完成。

nginx作者對其解釋,參考 http://blog.csdn.net/21aspnet/article/details/6604805 

Nginx中默認沒有添加對Etag標識.Igor Sysoev的觀點”在對靜態文件處理上看不出如何Etag好於Last-Modified標識。”
Note:
Yes, it's addition,and it's easy to add, however, I do not see howETag is better than Last-Modified for static files. -Igor Sysoev
A nice short description is here:
http://www.mnot.net/cache_docs/#WORK

7. expires和cache-control中max-age區別

nginx是在后台指定expires的間隔(比如7天后超期),然后nginx會自動在http頭中轉換成max-gae的時間,和頭中Expires會變換成具體的超期時刻(不是間隔了)

參考 https://www.bokeyy.com/post/high-performance-web-sites-rule3.html 

Max-age:在 HTTP 頭中按秒指定失效的時間,如下圖。好處是不像方法 1(expries) 一樣需要定時檢查是否過期,一旦過期就需要指定新的時間,壞處是只有 HTTP/1.1 支持

 

8. tomcat對304的處理

分析了tomcat6  閱讀其代碼 一目了然

protected boolean checkIfModifiedSince(HttpServletRequest request,
                                         HttpServletResponse response,
                                         ResourceAttributes resourceAttributes)
        throws IOException {
        try {
            long headerValue = request.getDateHeader("If-Modified-Since");
            long lastModified = resourceAttributes.getLastModified();
            if (headerValue != -1) {

                // If an If-None-Match header has been specified, if modified since
                // is ignored.
                if ((request.getHeader("If-None-Match") == null)
                    && (lastModified < headerValue + 1000)) {
                    // The entity has not been modified since the date
                    // specified by the client. This is not an error case.
                    response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
                    response.setHeader("ETag", resourceAttributes.getETag());

                    return false;
                }
            }
        } catch (IllegalArgumentException illegalArgument) {
            return true;
        }
        return true;

    }

HttpServletResponse.SC_NOT_MODIFIED  就是304狀態

resourceAttributes.getLastModified();  讀取文件上次修改時間。

有興趣的話可以繼續分析tomcat對etag的處理。

 

--EOF--


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM