當前位置:首頁 » 文件管理 » 靜態資源緩存

靜態資源緩存

發布時間: 2022-02-11 05:30:57

緩存靜態資源,不知怎麼解決

之前看過apach及nginx對於靜態資源(含js,圖片,css等)部分的緩存,用於加速並減輕後台實際web伺服器的壓力。
靜態資源緩存是WEB伺服器優化的一種手段,基本原理如下:
1.客戶端瀏覽器請求伺服器一個服務(該服務含有圖片,js等靜態資源),通常會對於每一個網頁中的獨立圖片或js文件發送一個http請求
2.WEB伺服器對於每個資源HTTP請求進行解析,並生成一個資源修改時間的唯一值(可以是etag或last_modified參數),放入伺服器端map,key為資源url,value為資源修改時間。最後將此資源修改時間的唯一值包含在http頭上返回,因為是首次請求,所以會將所有內容放在http body中一並返回給客戶瀏覽器端
3.客戶瀏覽器接收服伺服器響應,並將伺服器返回的資源修改時間作為key放入瀏覽器客戶端,value為http body中的實際資源內容
4.客戶瀏覽器再次請求靜態資源時,會將資源修改時間一並發送給伺服器
5.服務端會從最新的map中取出該資源url對應的修改時間,如果值晚於客戶端請求的資源修改時間,這時會返回最新的已經修改過的資源給客戶端。否則返回304 not modifed

這里記錄資源修改時間的方式有etag及last_modified。最先有的是last_modified,它的工作方式就是上述介紹的,但缺點是只能精確到秒級別。也就是說當你在一秒中修改資源兩次,而客戶端拿到的是第一次修改,那之後就算客戶端第二次再次請求也不會拿到最新的資源。
而etag的出現正是為了解決last_modified的秒級問題,於http 1.1被提出。

今天測試了下,在沒有nginx等前端反向代理伺服器時,tomcat竟然默認對靜態資源做了緩存。
tomcat默認運用etag及last_modifed。etag與if_no_match(客戶端瀏覽器上傳時在http head中應該放的屬性名)一起使用,last_modified與If-Modified-Since一起使用。

客戶端首次請求時,得到請求響應數據如下:

GET http://localhost:8080/webTest/jsp/index.jsp [HTTP/1.1 200 OK 1ms]
GET http://localhost:8080/webTest/js/hello.js [HTTP/1.1 200 OK 1ms]
GET http://localhost:8080/webTest/img/a.jpg [HTTP/1.1 200 OK 2ms]
我們看一下Hello.js這個請求響應具體信息:
server Apache-Coyote/1.1 (表明伺服器是tomcat)
Last-Modified: Sun, 11 May 2014 10:54:33 GMT
Etag: W/"175-1399805673000"
Date: Sun, 11 May 2014 10:59:23 GMT
Content-Type: application/javascript;charset=UTF-8
Content-Length: 175
Accept-Ranges: bytes

從上面可以看到tomcat即返回了last_modified也返回了etag。

客戶端再次請求時,請求數據如下:
If-None-Match: W/"175-1399805673000"
If-Modified-Since: Sun, 11 May 2014 10:54:33 GMT
響應如下:

GET http://localhost:8080/webTest/jsp/index.jsp [HTTP/1.1 200 OK 1ms]
GET http://localhost:8080/webTest/js/hello.js [HTTP/1.1 304 Not Modified 1ms]
GET http://localhost:8080/webTest/img/a.jpg [HTTP/1.1 304 Not Modified 1ms]
從中我們可以看到tomcat對於靜態數據作了緩存。

接著我們分析tomcat對於這部分靜態緩存的判斷處理,這部分邏輯是寫在DefaultServlet類中,
我們可以在doGet方法中進入ServiceContext方法中找到以下源碼
// Check if the conditions specified in the optional If headers are
// satisfied.
if (cacheEntry.context == null) {

// Checking If headers
boolean included =
(request.getAttribute(Globals.INCLUDE_CONTEXT_PATH_ATTR) != null);
if (!included
&& !checkIfHeaders(request, response, cacheEntry.attributes)) { //這句判斷是否需要返回整個資源請求
return;
}

}
上面源碼的 if (!included
&& !checkIfHeaders(request, response, cacheEntry.attributes))
用於判斷是否需要返回整個資源,如果indcluded與checkIfHeaders方法返回的都是false,這時就直接返回,說明資源未修改,或者是緩存不支持的請求方式。
我們接著查看checkIfHeaders方法:
/**
* Check if the conditions specified in the optional If headers are
* satisfied.
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
* @param resourceAttributes The resource information
* @return boolean true if the resource meets all the specified conditions,
* and false if any of the conditions is not satisfied, in which case
* request processing is stopped
*/
protected boolean checkIfHeaders(HttpServletRequest request,
HttpServletResponse response,
ResourceAttributes resourceAttributes)
throws IOException {

return checkIfMatch(request, response, resourceAttributes)
&& checkIfModifiedSince(request, response, resourceAttributes)
&& checkIfNoneMatch(request, response, resourceAttributes)
&& checkIfUnmodifiedSince(request, response, resourceAttributes);

}

可以看到tomcat只有當這四個屬性全部返回true(也就是說全部認為資源已經改變)才會返回true,這樣最終會將整個資源(最新修改過的)返回客戶端。
在這里,我們從上面實際過程當中看到,瀏覽器第二次請求資源時在http請求header中放了
If-None-Match: W/"175-1399805673000"
If-Modified-Since: Sun, 11 May 2014 10:54:33 GMT
這兩個屬性。
因此我們查看
&& checkIfModifiedSince(request, response, resourceAttributes)
&& checkIfNoneMatch(request, response, resourceAttributes)
這兩個方法
checkIfModifiedSince源碼如下:
/**
* Check if the if-modified-since condition is satisfied.
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
* @param resourceInfo File object
* @return boolean true if the resource meets the specified condition,
* and false if the condition is not satisfied, in which case request
* processing is stopped
*/
protected boolean checkIfModifiedSince(HttpServletRequest request,
HttpServletResponse response,
ResourceAttributes resourceAttributes) {
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;

}
源碼中可以看到:
if ((request.getHeader("If-None-Match") == null)
&& (lastModified < headerValue + 1000)) {
這句話表明只有在客戶端瀏覽器發送的請求頭中不包含If-None-Match,IfModifiedSince才會生效。
我們接著看checkIfNoneMatch,源碼如下:
/**
* Check if the if-none-match condition is satisfied.
*
* @param request The servlet request we are processing
* @param response The servlet response we are creating
* @param resourceInfo File object
* @return boolean true if the resource meets the specified condition,
* and false if the condition is not satisfied, in which case request
* processing is stopped
*/
protected boolean checkIfNoneMatch(HttpServletRequest request,
HttpServletResponse response,
ResourceAttributes resourceAttributes)
throws IOException {

String eTag = resourceAttributes.getETag();
String headerValue = request.getHeader("If-None-Match");
if (headerValue != null) {

boolean conditionSatisfied = false;

if (!headerValue.equals("*")) {

StringTokenizer commaTokenizer =
new StringTokenizer(headerValue, ",");

while (!conditionSatisfied && commaTokenizer.hasMoreTokens()) {
String currentToken = commaTokenizer.nextToken();
if (currentToken.trim().equals(eTag))
conditionSatisfied = true;
}

} else {
conditionSatisfied = true;
}

if (conditionSatisfied) {

// For GET and HEAD, we should respond with
// 304 Not Modified.
// For every other method, 412 Precondition Failed is sent
// back.
if ( ("GET".equals(request.getMethod()))
|| ("HEAD".equals(request.getMethod())) ) {
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
response.setHeader("ETag", eTag);

return false;
}
response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
return false;
}
}
return true;

}
這里:
String eTag = resourceAttributes.getETag();
String headerValue = request.getHeader("If-None-Match");
這兩句比較簡單,就是分別從伺服器緩存和http請求頭中中取出etag。
接著判斷這兩個etag如果相等,則conditionSatisfied為true,會執行到以下語句:
if (conditionSatisfied) {

// For GET and HEAD, we should respond with
// 304 Not Modified.
// For every other method, 412 Precondition Failed is sent
// back.
if ( ("GET".equals(request.getMethod()))
|| ("HEAD".equals(request.getMethod())) ) {
response.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
response.setHeader("ETag", eTag);

return false;
}
response.sendError(HttpServletResponse.SC_PRECONDITION_FAILED);
return false;
}
這段語句中可以發現,如果資源未改變的情況下,並且請求方式為GET或者HEAD時,會返回304狀態碼。否則返回一個412狀態碼,同樣不會返回資源內容。
如果上述最終
if ((request.getHeader("If-None-Match") == null)
&& (lastModified < headerValue + 1000))
條件不成立,即資源更新了或者是第一次請求,這里會讀取當前請求資源文件,並最終放入http響應中。

⑵ ios中webview怎麼做靜態資源的緩存

1、在重寫onkeydown方法 即可,例如: @Override public boolean dispatchKeyEvent(KeyEvent event) { if (event.getKeyCode() == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN && event.getRepeatCount() == 0) { goback } return super.dispatchKeyEvent(event); } 2、這個方法就可以監聽按鈕返回鍵或者簡直返回鍵操作。 3、return false就禁止返回。

⑶ 如何為WordPress和Typecho設置靜態資源緩存

在HTTP標頭中為靜態資源設置過期日期或最長存在時間,可指示瀏覽器從本地磁碟中載入以前下載的資源,而不是通過網路載入。這樣, 網站載入速度會更快.
下面的代碼都需要放到.htaccess中才能生效. 推薦設置過期時間為一個月, 即: max-age=2592000.
####通過FilesMatch設置
<FilesMatch ".(flv|gif|jpg|jpeg|png|ico|swf|css|js)$">
Header set Cache-Control "max-age=2592000"
</FilesMatch>
####通過mod_expires.c設置
<IfMole mod_expires.c>
ExpiresActive On
ExpiresDefault "access plus 1 months"
ExpiresByType text/html "access plus 1 months"
ExpiresByType image/gif "access plus 1 months"
ExpiresByType image/jpeg "access plus 2 months"
ExpiresByType application/x-shockwave-flash "access plus 2 months"
ExpiresByType application/x-javascript "access plus 2 months"
</IfMole>
如需針對具體的資源類型需要這樣:
ExpiresByType image/gif "access plus 5 hours 3 minutes"
更多規則參考Apache Mole mod_expires.
參考來源:
Cache Control with htaccess FILES MATCH
Apache里配置 mod_expires 和 mod_headers 以支持CACHE
Tags: wordpress靜態資源緩存, typecho靜態資源緩存, wordpress瀏覽器緩存, typecho瀏覽器緩存, 靜態資源緩存, 瀏覽器緩存,wordpress cache expire, typecho cache expire

⑷ 如何將靜態資源緩存在cdn節點上

首先要糾正這個問題,動態內容是沒辦法緩存的。
動態內容需要的是信息的實時交互,如果採用了緩存,會影響正常業務。
舉個例子,國航官網,訂票內容就是動態的,如果這時候將這部分進行緩存,那當用戶訂票的時候,官網顯示剩餘10張票,並且在緩存過期內,會一直顯示10張票。而實際資料庫里已經沒有票了。這時候勢必會影響到客戶體驗。

動態內容的CDN加速其實還是鏈路和協議的優化。
首先,國內ISP復雜,南北互通的問題,會導致訪問速度慢,CDN廠商有覆蓋全國的PBL網路(可以理解為CDN提供商自己的私有網路,獨立的ISP),當採用動態加速時,將內容引入CDN供應商的網路內,再根據分布在全國的CDN節點作為接入和落地口,達到鏈路的最優。
其次,CDN供應商會針對TCP等協議進行優化和調整,使正常的TCP三次握手減少到1次,從而減少計算機與計算機、路由之間的信息傳遞環節,從而達到加速目的。

⑸ 如何解決網站靜態頁緩存問題

使用靜態頁緩存提升網站性能,變化很少的靜態資源可以設置客戶端緩存時間,減少請求。
如果一定要不要靜態頁緩存,可以設置頁面不緩存靜態頁面,這個要根據實際的WEB應用服務進行設置了。

⑹ 為什麼要把靜態資源放在WEB-INF下

方法一:javaWeb的程序如果使用的開發工具是Eclipse,那麼在項目下回自動生成一個WebContent文件夾,使用的是MyEclipse工具開發,那麼會有個WebRoot文件夾。方法2:javaWeb工程的話一定會有jsp文件存在的啦javaWeb工程作為java工程導入

⑺ 給靜態資源的header加控制緩存的參數有多大意義

讓靜態資源不被SpringMVC分配器過濾有兩種法:①把所有的JS和CSS文件移至別的文件夾②為resources文件夾需要被過濾的文件類型分別寫一個mapping第二種方法是在web.xml配置靜態資源映射到default去吧。第一種方法意思是,比如之前的目錄結構是把css,js放在webroot下的resources文件夾中,頁面上通過這樣的請求來訪問。

⑻ 做前端靜態資源緩存伺服器有哪些成熟易搭建的方案

我現在是把阿里雲的 CDN 直接解析到 OSS 。

每天的 PV , 1 萬到 5 萬。

然而才用了一個多月就跑了 300+G 流量。 0.36/GB 。淚。

阿里雲的 CDN 實在是太貴了,用峰值帶寬的話,根本就不能控製成本啊!萬一有個用戶 100M 水管,那一天豈不是要付 100 塊錢?

所以還不如選一個好一點的 BGP 線路機器反代到 OSS 。

自己用 squid 搭建嗎?
如果主站是 HTTPS 的, squid 能配置 SSL 嗎?還是說要 nginx 配置 SSL 以後再去反代 squid ,然後 squid 反代 oss ?
有沒有配置腳本
還是裝個 AMH/WDCP 之類面板,然後可以傻瓜化配置?

對主機磁碟 IO 、內存有什麼要求?

⑼ 靜態資源存儲在localStorage有什麼缺點

1.localStorage一般只能存5m。 2.老的瀏覽器不支持HTML5。 3.有些瀏覽器如果使用『無痕瀏覽模式『會禁用localStorage的setItem方法。 建議:用localStorage作為一個不可靠的緩存使用,優化性能(如:緩存ajax請求),而不是作為資料庫使用。

⑽ springmvc 怎麼清除前台靜態資源緩存

讓靜態資源不被SpringMVC分配器過濾有兩種辦法:
① 把所有的 JS 和 CSS 文件移至別的文件夾
② 為 resources 文件夾需要被過濾的文件類型分別寫一個 mapping

第二種方法是在web.xml配置靜態資源映射到default去吧。
第一種方法意思是,比如之前的目錄結構是把css,js放在webroot下的resources文件夾中,頁面上通過 這樣的請求來訪問。

熱點內容
抗生素資料庫 發布:2024-04-19 22:13:03 瀏覽:495
晚晚教編程 發布:2024-04-19 21:56:23 瀏覽:712
安卓換蘋果語音留言怎麼看 發布:2024-04-19 21:56:21 瀏覽:627
解壓神經 發布:2024-04-19 21:47:03 瀏覽:894
c語言字元轉義字元 發布:2024-04-19 21:43:51 瀏覽:727
mysql存儲過程語法 發布:2024-04-19 21:00:04 瀏覽:245
修復損壞的壓縮文件 發布:2024-04-19 20:53:32 瀏覽:423
編程發型 發布:2024-04-19 20:53:28 瀏覽:500
去除空格sql 發布:2024-04-19 20:43:30 瀏覽:785
linuxcp覆蓋 發布:2024-04-19 20:43:30 瀏覽:189