Apache 不會為靜態檔案提供 304 Not Modified 回應

Apache 不會為靜態檔案提供 304 Not Modified 回應

我正在運行一個 Apache Web 伺服器,從檔案系統提供大型靜態映像。我已將伺服器配置為返回有效的快取標頭,如下所示:Header merge Cache-Control "public, max-age=31536000, immutable"

這一切都很好,但是當用戶在瀏覽器中重新載入圖像時,Apache 永遠不會回傳回應304 Not Modified

我運行了這個curl命令(出於保密原因我更改了主機名稱):

curl -o /tmp/image.png -v -u test:example http://blah.example.com/static/images/covers/436g2gu94kxin4x7

以下是來自curl 的請求標頭。

GET /static/images/covers/436g2gu94kxin4x7 HTTP/1.1
Host: blah.example.com
Authorization: Basic dGVzdDpleGFtcGxl
User-Agent: curl/7.64.1
Accept: */*
If-Modified-Since: Thu, 30 Apr 2020 02:21:47 GMT

我預計會收到 304 回應,但我得到的是:

HTTP/1.1 200 OK
Date: Fri, 28 Aug 2020 04:59:54 GMT
Server: Apache/2.4.25 (Debian)
Content-Type: image/png
Content-Length: 3115720
Last-Modified: Thu, 30 Apr 2020 02:21:47 GMT
Vary: Accept-Encoding
Cache-Control: public, max-age=31536000, immutable

我讀過Apache 快取指南,但似乎都與這種情況無關……這都是關於配置 Apache 自己的緩存,無論是在內存中還是在磁碟上,特別是支援 Apache 充當原始伺服器的反向代理的情況。

但在這種情況下,檔案已經位於本機磁碟上。沒有來源伺服器。我不希望/不需要 Apache 儲存檔案的單獨“快取”副本;我只是想讓 Apache 注意到Last-Modified磁碟上文件的日期與日期匹配並在這種情況下If-Modified-Since返回。304 Not Modified

我該如何設定?我是否必須讓 Apache 儲存自己單獨的檔案快取副本才能啟用條件 GET? (這將是一個非常大的緩存,大概存儲在磁碟上,這完全是浪費。)

答案1

首先,它真的不緩存嗎?

捲曲可能是你的問題。我厭倦了你在一個我知道返回 304 的 URL 上的程式碼,並且使用上面的程式碼它總是返回 200。您是否嘗試過網頁瀏覽器的開發人員工具?只要未選取“停用快取”,您就應該能夠刷新 URL 並在第二次刷新時看到它返回 304。

其次,這可能是 Apache 的 bug

我在您的結果中沒有看到 ETag 標頭。假設 Apache 確實沒有添加此內容,那麼您可能可以忽略此內容。但您仍然可以嘗試將其添加到您的 Apache 設定中,以防萬一:

<IfModule mod_headers.c>
    Header unset ETag
</IfModule>
FileETag None

(請務必使用 啟用 headers mod a2enmod headers。)

或者,更好的是,如果您使用的是 Apache 2.4.42 及更高版本 ( apache2 -v),您可以在設定中嘗試以下操作:

<IfModule mod_deflate.c>
    DeflateAlterETag NoChange
</IfModule>

此問題是由 deflate 模組在 ETag 末端添加壓縮方法所引起的。這導致 Apache 忽略快取並始終返回 200。

....防止對壓縮內容的條件請求提供「HTTP 未修改」(304) 回應。

Apache 模組 mod_deflate

因此禁用它可以解決一些快取問題。

相關內容