Optimize Browser Caching(小記)

(1)Cache-Control,用來減小http請求
在server, response的header中,增長以下內容
response.setHeader("Cache-Control", "max-age=31536000,public");

 瀏覽器在收到此header後。將該url對應的內容緩存max-age(單位:秒)這麼久,在這個時期內,刷新頁面,瀏覽器將會使用本地緩存,不會發任何http請求 java


此時在DragonFlag上觀察,能夠清楚的看到no request made web

 注意:這裏的刷新是指在地址欄按回車!而不是F5或Ctrl+F5!,每種瀏覽器對F5的處理都不相同,請看下錶: 瀏覽器

http://stackoverflow.com/questions/385367/what-requests-do-browsers-f5-and-ctrl-f5-refreshes-generate 緩存


若是在request 的header中的使用了Cache-Control(好比強制刷新就會在request中產生該header),此時會覆蓋response中的值。也就是說瀏覽器的設置能夠改變server的response方式。 服務器


(2)Expires(用途和Cache-Control同樣,減小http請求) fetch


(3)Last-Modified(用來減小數據傳輸,請求不會少:) this

 這個和以上兩個header做用都不同。 url

讓咱們看一下整個過程: spa

首先瀏覽器向server請求一個資源,request header中並不包含任何特別信息 debug

服務器收到該請求,以爲這個資源若是反覆訪問浪費流量,因而它在header中

在server, response的header中,增長以下內容
response.setDateHeader("Last-Modified",資源最後修改時間對應的毫秒數));

瀏覽器訪問到了所須要的資源,還發現了server增長的這個額外的時間信息。.


在下次請求該資源時,瀏覽器將上次server發過來的Last-Modified的值回傳給server, 值不變,只是換了個名字(If-Modified-Since),也就是說瀏覽器在第二次請求資源時發出的header中會包含If-Modified-Since,


服務器再次接收到該請求,發現request header中包含有If-Modified-Since,

它明白了:瀏覽器只要想問下該資源有沒有過時。

服務器對比該時間和資源的最後修改時間,若是資源已通過期,則發送資源,若是沒有,則響應304,不傳輸內容。


瀏覽器收到了304信息, 明白了,資源並無過時,繼續使用本身的緩存。


若是是靜態圖片,web server會自動幫你加上這個響應頭,而且會本身判斷資源有沒有過時,若是是動態內容,則本身虛擬一個時間,像這樣:
response.setDateHeader("Last-Modified",Long.valueOf(updated_time_stamp));

判斷資源是否過時也要本身實現,詳見最後的代碼,若是資源未過時,則響應304給瀏覽器,像這樣
        response.setStatus(HttpStatus.SC_NOT_MODIFIED);

下圖是瀏覽器第二次請求某資源時的狀況,上面的框框是請求,下面的框框是響應

 


最終全部代碼都在這
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String imageId = request.getParameter("imageId");
log.debug("GetImage imageId=" + imageId);
// updated_time_stamp is the same as in table SERVICE_DESCRIPTOR,and changes rarely.
String updated_time_stamp = request.getParameter("updated_time_stamp");
// if response set this header, the browser will send request with a
// header "If-Modified-Since" using the value here
response.setDateHeader("Last-Modified",Long.valueOf(updated_time_stamp));
// If-Modified-Since:the first time it is null, then it's assigned a value of Last-Modified the line above,
// this assignment is made automatically by browser
long ifModifiedSince = request.getDateHeader("If-Modified-Since");
// if once sent a request, the ifModifiedSince should not be -1 here
if (ifModifiedSince != -1) {
long updated_ts = Long.valueOf(updated_time_stamp);
// if not newer, just send a 304 response.
if (updated_ts / 1000 <= ifModifiedSince / 1000) {
log.debug("response with 304 ******************");
response.setStatus(HttpStatus.SC_NOT_MODIFIED);
return;
}
}
// only fetch when after clear cache or thumb-nail is changed in table SERVICE_DESCRIPTOR
try {
log.debug("reload image =====================");
Integer imageIdNumeric = Integer.decode(imageId);
HelperServiceLocal helperLocal = helperServiceHome.create();
Image image = helperLocal.getImage(imageIdNumeric);
// HTTP1.1,cache thumb-nail for one year, in some case, no request made if use this header
response.setHeader("Cache-Control", "max-age=31536000,public");
// HTTP1.0
Calendar cal = Calendar.getInstance();
cal.add(Calendar.YEAR, 1);
response.setDateHeader("Expires", cal.getTime().getTime());
response.setContentType(image.getContentType());
response.getOutputStream().write(image.getImage());
} catch (Exception e) {
log.error(e.getMessage(), e);
}
response.flushBuffer();
}


辛苦所寫,備用!
相關文章
相關標籤/搜索