檔案下載一直抓到舊檔案的問題
遇到問題
最近用 .NET Core 做動態依照資料庫使用者會帶過來參數去尋找檔案路徑做回傳下載。下載檔案都是舊版本。我看Console 的 Network 都是 200
。也沒有看到 204
抓Cache 的結果。這到底是為什麼呢?今天遇到我覺得要把這個問題找到。
這邊說這麼詳細是怕有各種情境有可能就會有不一樣結果。
簡單實驗
後來抓到檔案因為我們沒有設定Cache-Control
,然後動態下載檔案他的Last-Modified
是當下時間可能是檔案異動時間。這邊雖然我沒給Last-Modified
,是程式內部機制給的時間,雖然好像可以設定Last-Modified
,但我發現再次跑檔案根本沒有進 Server 取檔案。仔細看Console 顯示200 磁碟快取
,我覺得一定有什麼關係取到快取。雖然網路上很多交用Cache-Control: no-cache
或 max-age=xxx
,但我覺得要了解為什麼比較重要。
這邊用小遊戲下載網隨便一個檔案來Demo
第一次跑
第二次跑
我找到這篇http - What happens if you don’t set cache-control header? - Webmasters Stack Exchange。
裡面提到Chrome 至少 Cache 一個禮拜和(current time - last modified time) / 10
兩者最小值。Firefox 規則又不太一樣。每一家實作不一樣,真的不好找阿…
我觀察Github Release 下載檔案做的事情,他下載是有做Cache-Control: no-cache
,不過我視覺的能不能設定個60秒
之類的會比不會比較好,減少 Server Loading。
找到問題
沒有副檔名的時候不會發送If-Modified-Since
。上面測小遊戲下載網隨便一個檔案來Demo
的exe檔案,請求(Request)竟然不會帶到這個header If-Modified-Since
。不過我這邊放在hfs上面,發現能抓到cache。但把test7z
(沒有副檔名)放在hfs下載,兩次下載都會吃到Cache。
所以我推知之前用程式指向路徑做下載,應該是採到 URL 沒有副檔名關係,所以都會吃到Cache。所以程式做這些事情可能要留意一下這個問題。
第一次
第二次
簡單說重點
我發現當沒有 Cache-Control
時候瀏覽器還是會做緩存,預設為(current time - last modified time) / 10
,但這部分是找到相關資料,所以沒有什麼動作就會有緩存動作。這讓我想到以前做後端回傳報表資料都會有緩存問題,但有可能是這個問題。但這個緩存問題有時很複雜,有可能是 Server 吃住 Cache 導致,有可能要重啟服務才能跑。
解決方法
程式指向檔案最好加上Cache-Control: no-cache
或max-age
就好。這邊我選擇的是控制max-age
。至少有一分鐘緩存,User一直狂點連結那一小時都是緩存的。
.Net Core
這邊留 .Net Core 解決方法。
ASP.NET Core 中的回應快取 | Microsoft Docs
|
|
19.研究OutputCache、ResponseCache兩快取差異 - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天
Spring Boot
Laravel
-
php - Laravel 5 how to set Cache-Control HTTP header globally? - Stack Overflow
-
Laravel 中间件 SetCacheHeaders (etag/no-cache/max-age) | Laravel优质外文翻译 | Laravel China 社区
文章
緩存還有很多東西還沒,有分舊版和新版,甚至瀏覽器重新整理會帶的 Request也會不一樣。
其他參考
caching - What’s default value of cache-control? - Stack Overflow