2010-03-11 48 views
31

這是關於爲圖像提供服務的Web應用程序。由於相同的請求將始終返回相同的圖像,因此我希望訪問瀏覽器儘可能積極地緩存圖像。我非常想告訴瀏覽器要求瀏覽器儘可能積極緩存

這是您的圖片。繼續保持它;在接下來的幾天裏它真的不會改變。不需要回來。真。我承諾。

我做的,到目前爲止,設置

Cache-Control: public, max-age=86400 
Last-Modified: (some time ago) 
Expires: (two days from now)

,當然返回304 not modified如果要求有適當的If-Modified-Since頭。

還有什麼我可以做的(或者我應該做的不同)我的消息傳遞給瀏覽器?

該應用程序託管在Google App Engine上,以防萬一。

+5

如果它不會改變,每日1次的到期時間(*最大年齡*)不算多。 – Gumbo 2010-03-18 10:24:18

+0

@Gumbo:真的;正如我在Sripathi Krishnan的回答中指出的那樣,這肯定會有所增加。我仍然想知道爲什麼Gravatar只將它設置爲5分鐘。 – balpha 2010-03-19 15:10:52

+0

你可以改變你的gravatar,所以它是有道理的。 – 2010-05-27 02:36:44

回答

12

你可能有興趣在檢查出下面的谷歌代碼的文章:

簡而言之,所有現代瀏覽器應該能夠適當地緩存您的圖片的指示,與HTTP標頭。

+1

這是一個有趣的閱讀;謝謝。 – balpha 2010-03-11 15:55:33

1

嘗試的.htaccess像

<ifmodule mod_gzip.c> 
    mod_gzip_on Yes 
    mod_gzip_dechunk Yes 
    mod_gzip_item_include file \.(html?|txt|css|js|php|pl)$ 
    mod_gzip_item_include handler ^cgi-script$ 
    mod_gzip_item_include mime ^text/.* 
    mod_gzip_item_include mime ^application/x-javascript.* 
    mod_gzip_item_exclude mime ^image/.* 
    mod_gzip_item_exclude rspheader ^Content-Encoding:.*gzip.* 
</ifmodule> 

<ifmodule mod_deflate.c> 
AddType application/x-compress .Z 
AddType application/x-gzip .gz .tgz 
AddType application/x-httpd-php .php 
AddType application/x-httpd-php .php3 
AddOutputFilterByType DEFLATE text/html 
AddOutputFilterByType DEFLATE text/plain 
AddOutputFilterByType DEFLATE text/xml 
AddOutputFilterByType DEFLATE application/x-httpd-php 
AddOutputFilterByType DEFLATE application/x-javascript 
</ifmodule> 

<ifmodule mod_expires.c> 
    ExpiresActive On 
    ExpiresDefault "access plus 1 seconds" 
    ExpiresByType text/html "access plus 1 seconds" 
    ExpiresByType image/gif "access plus 2592000 seconds" 
    ExpiresByType image/jpeg "access plus 2592000 seconds" 
    ExpiresByType image/png "access plus 2592000 seconds" 
    ExpiresByType text/css "access plus 604800 seconds" 
    ExpiresByType text/javascript "access plus 216000 seconds" 
    ExpiresByType application/x-javascript "access plus 216000 seconds" 
</ifmodule> 

<ifmodule mod_headers.c> 
    <filesMatch "\\.(ico|pdf|flv|jpg|jpeg|png|gif|swf)$"> 
    Header set Cache-Control "max-age=2592000, public" 
    </filesmatch> 
    <filesMatch "\\.(css)$"> 
    Header set Cache-Control "max-age=604800, public" 
    </filesmatch> 
    <filesMatch "\\.(js)$"> 
    Header set Cache-Control "max-age=216000, private" 
    </filesmatch> 
    <filesMatch "\\.(xml|txt)$"> 
    Header set Cache-Control "max-age=216000, public, must-revalidate" 
    </filesmatch> 
    <filesMatch "\\.(html|htm|php)$"> 
    Header set Cache-Control "max-age=1, private, must-revalidate" 
    </filesmatch> 
</ifmodule> 
+0

該應用程序位於Google App Engine上;沒有'.htaccess'(或Apache,對於這個問題) – balpha 2010-03-11 16:36:56

+0

哎呀,我忽略了這一點。無論如何都要保持它,以便它可以幫助那些與Apache。 – 2010-03-14 06:45:40

10

你可以做的更好。 304s仍然是一個HTTP請求/響應。雖然圖像不會再次下載,但延遲可能會被破壞。

如果您可以在圖像名稱中包含版本標識符,則可以將最大年齡設置爲2年。這樣,你可以防止304s。如果圖像發生更改,則更新版本標識符,從而更改文件名稱。這確保瀏覽器將發出新的請求。

它需要對您的項目結構進行一些更改。版本標識符可以是上次更新映像時的SVN修訂版本號,並且可以在構建時自動生成。你還需要更新html,所以如果你有一個圖像名稱和圖像路徑之間的邏輯映射,你的工作會更容易。

圖像很少更新,因此如果您無法自動執行上述操作,您也可以採用手動方法。訣竅是隻添加新圖像,不要修改它們。

+0

這些是一些好主意。長時間的最大年齡是我絕對要做的事情;儘管我認爲根據RFC,我讀了一年是允許的最大值。版本標識符是我想過的,但不幸的是它不是一個選項。該應用只是將圖像包含在其他網頁中(像Gravatar一樣思考)。 – balpha 2010-03-12 16:51:47

+0

@Sripathi Krishnan:但是殺死延遲似乎無法避免!瀏覽器在每次關閉瀏覽器並在同一頁面上再次打開它時,甚至會使用'mod_expires'重新爲圖像發出HTTP請求。它不會在服務器響應後下載映像,但它仍會查詢服務器,從而增加延遲。看到我的問題,也許你有一個想法:http:// stackoverflow。com/questions/10048740/stop-browser-to-make-http-requests-for-images-that-should-stay-cached-mod-expi – 2012-04-07 19:18:19

+0

根據rfc2616的第14.21節,「HTTP/1.1服務器不應該發送Expires日期將在一年以上。「;一年的最大值。 – 2014-05-21 14:54:43

2

有,你有沒有在這裏提到的緩存頭非常重要的價值:

「後的檢查= 900,預檢查= 3600」

閱讀這篇文章關於這個話題(和尋找更多):

http://www.rdlt.com/cache-control-post-check-pre-check.html

+4

這很有趣,謝謝。有幾件事值得一提:這只是IE瀏覽器,鏈接到自己的帖子鏈接到一篇相當古老的文章,並且我沒有發現任何關於「您的客戶端瀏覽器總是詢問......」的提及;完全相反,在評論線程中有許多跡象表明IE確實遵守標準頭文件。 – balpha 2010-03-17 15:42:18

+0

也許只用於ie,我不知道。我所知道的是,我在開發人員工具上看到了google chrome和mozilla firefox,從我放置這個值的那一刻起,就是停止獲取所有時間,圖像。事實是,我的工作很快,而且在我看到效果更好之後,並沒有檢查得太深。也許在Chrome的源代碼裏面,如果使用這個值,那麼就有一個真正的缺陷。 – Aristos 2010-03-18 09:31:29

+0

我刪除了「沒有該標題,即使您設置了您提到的標題,您的客戶瀏覽器也會始終詢問您的頁面和圖像。」因爲我沒有檢查它的原因。 我也發現這篇文章的相對。 http://www.google.co.uk/support/forum/p/Chrome/thread?tid=384b6abc105a67e5&hl=en – Aristos 2010-03-18 09:33:48

2

我不知道日它將超越其他人提供的解決方案,但您可以使用HTML5 offline web apps工具來更明確地要求瀏覽器存儲本地副本。

+0

這是一個好主意。這對我來說無濟於事(因爲我只提供圖像,我不控制包含這些圖像的頁面的HTML)。但是對於一般情況來說很好。 +1 – balpha 2010-03-17 15:44:41

1

可以添加ETag表示爲每個圖像,然後把它比作在入站請求If-None-Match頭(見「Why isn’t my custom delivered image caching in the browser?」)。這在使用首選的Last-Modified標題時是多餘的,並且它只是用於說出304的另一種方式。 (我認爲GAE會自動爲靜態文件執行此操作,但不確定。)

Gravatar設置很舊Last-Modified日期 - 默認情況似乎是「星期三,1984年1月11日08:00:00 GMT」。 5分鐘到期會導致瀏覽器頻繁檢查更新的圖像。換句話說,我認爲他們正在邀請304s,而不是試圖說服瀏覽器只使用本地緩存。他們的標題看起來像這樣:

Date: Sat, 20 Mar 2010 07:52:43 GMT 
Last-Modified: Wed, 11 Jan 1984 08:00:00 GMT 
Expires: Sat, 20 Mar 2010 07:57:43 GMT 
Cache-Control: max-age=300 

最大的區別是過期時間 - 你想要兩天,他們想要五分鐘。因此,如果你想讓瀏覽器在48小時內使用緩存圖像,請執行你正在做的操作,只設置Cache-Control: max-age=172800(86400是24小時)。

1

幾天緩存時間非常低。你應該把它設置爲一年或更多。 當然,這可能會引起圖像實際更改時出現的問題,但您可以通過向圖像添加版本號並更改引用圖像的頁面以包含新圖像的路徑來解決該問題。

我寫了更多關於Web應用程序的緩存位置: http://patchlog.com/web/7-methods-to-cache-web-applications/

+0

你在開玩笑嗎?我都是爲了這個疑問而感到受益,我總是很感激人們給我答案的任何提示或幫助。但是寫作與Sripathi Krishnan在一週之前寫的幾乎一樣(只是更詳細的內容),只是爲了鏈接到你錯誤的相關博客文章 - 我稱之爲垃圾郵件。 – balpha 2010-03-20 16:56:17

+0

這可能很難相信,但在發佈之前我沒有看到他的答案。而且我的帖子也有關於緩存的更多想法,但是當然更容易忽略某些內容,只是投票而不是閱讀相當長的文章。 – 2010-03-20 19:11:37

+0

相信與否,downvote不是我的。儘管如此,您的博客文章(我根本找不到冗長的文本;在接受的答案中鏈接的文本要長得多)與我的問題無關。 – balpha 2010-03-20 19:33:41