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

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

1. 討論涉及的要點

訪問返回類html

> 訪問返回200 OKjava

> 訪問返回200 (from memory cache)nginx

> 訪問返回200 (from disk cache)web

> 訪問返回304 Not Modifiedchrome

頭設置類ubuntu

> 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--

相關文章
相關標籤/搜索