2009-04-16 95 views
1

在我們的項目中,我們有一大堆小的css/js文件,所以當我們構建視圖時,我們發現自己寫了很多<link><script>標籤,迫使瀏覽器對我們的css/js內容提出許多請求。爲了解決這個問題,我們開始尋找一種服務器支持的方式,將所有請求轉化爲一個請求,將每個css文件或與該操作關聯的每個js文件轉儲到響應中。強制瀏覽器緩存對Castle MonoRail操作的請求?

沒有進入太多細節,我們創建了一個助手類,接受文件,連接起來,然後呈現一個標籤,像這樣:

<script type="text/javascript" src="/content/js15628453.rails"></script>

的ContentController則具有使用默認的行動「 js15628453'找到Helper存儲連接文件的位置並將其流出。這工作得很好。

但是,正如Firebug報告的那樣,瀏覽器始終會發送一個請求到「/content/js15628453.rails」以獲取連接文件,儘管URL始終是相同的,並且響應始終是相同的。我嘗試過所有類型的HTTP Cache-Control,Expires,Last-Modified等標題的組合,但尚未得到Firebug從緩存中加載的報告。

爲什麼瀏覽器可能忽略這些頭文件?有沒有其他選擇我可以嘗試強制它被緩存?

回答

2

那麼,我想到了這一點,以便爲那些可能在搜索引擎中找到這個問題的人帶來好處,我會繼續並回答我自己的問題。

基本上,我不得不寫來設置一個304個狀態自己的邏輯:

DateTime lastModified = // some date 
string ifModifiedSince = Request.Headers["If-Modified-Since"]; 
if (ifModifiedSince != null) 
{ 
    var requestDate = DateTime.Parse(ifModifiedSince); 
    if (requestDate <= lastModified) 
    { 
     CancelView(); 
     Response.StatusCode = 304; 
     return; 
    } 
} 

Response.CachePolicy.SetLastModified(lastModified); 

// Logic to write the file to the OutputStream 

我錯誤地以爲瀏覽器將只使用它的緩存副本,如果它的存在,並沒有過期,而它顯然需要詢問服務器其緩存副本是否仍然有效。

1

@Tinister: 那麼實際上你做的是處理條件GET 那就是 - 當一個Get請求並從客戶機到服務器,問:「你有什麼比X更新」和服務器說304,如果不。 你確實避免了生成js的服務器和js內容的流量,但是請求的成本(即 - 從瀏覽器發送http請求到服務器)仍然存在。 這個東西正在被Last-Modified/IfMOdifiedThen Headers(一個用於響應,一個用於請求)和/或ETAG頭部處理。

緩存是一個不同的事情 - 即當瀏覽器決定不發出GET請求時。它由「Expires」標頭或Cache-control標頭管理。

您可能會在某處設置Cache-Control標頭,並使客戶端忽略「Expires」。 嘗試設置「max-age 360​​0」或類似的東西,看看請求是否被緩存(忘了關於FB - 而不是設置斷點或登錄服務器以確保它不被調用)

說 - 在處理js/css文件時 - 你可能不會想要實際的緩存。那是因爲如果瀏覽器決定緩存,比如一週,那麼你不能強制它重新加載一個新版本。因此,如果您將新版本部署到服務器,則無論新資源的新時間(oe etag)如何,客戶端都會在一週過後纔會看到它 - 因爲它永遠不會發出條件GET請求。一個解決方案(如果你真的想減輕網絡安全性)是設置最大時間(比如一年)的緩存,當資源改變時,你改變URI(按原樣 - 添加一個任意的查詢字符串值)。這將迫使瀏覽器重新加載新的js資源,並且永遠不會再次打擾服務器,至少直到下一次更新+下一個資源URI

0

我注意到至少firefox似乎利用「最後修改」當計算它是否處理HEAD請求時檢查「未修改」(304)響應代碼的初始請求。

有一個非常古老的「最後修改」時間戳看起來會導致它不檢查該文件的任何新版本,除非明確要求。

但是,我不會嚴重依賴這一點。