Mengapa Apache mengirim 200 OK saat pertandingan yang dimodifikasi terakhir Jika dimodifikasi-sejak?

10

Saya mencoba untuk memiliki perilaku dasar mengenai strategi caching saya: file harus di-cache, dan divalidasi kembali dengan server setiap kali. Jadi saya ingin Apache mengirim kembali 304.

Berikut adalah dialog yang terjadi untuk setiap pembaruan browser:

Status Code:200 OK

Request Headers

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip,deflate,sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Cache-Control:max-age=0
Connection:keep-alive
Cookie: ...
Host:...
If-Modified-Since:Tue, 14 Oct 2014 15:10:37 GMT
If-None-Match:"1461-505636af08fcd-gzip"
User-Agent:Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36

Response Headers

Accept-Ranges:bytes
Cache-Control:No-cache
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:1412
Content-Type:text/html
Date:Tue, 14 Oct 2014 16:58:05 GMT
ETag:"1461-505636af08fcd-gzip"
Keep-Alive:timeout=5, max=99
Last-Modified:Tue, 14 Oct 2014 15:10:37 GMT
Server:Apache/2.4.6 (Ubuntu)
Vary:Accept-Encoding

(ini dari chrome devtools, dengan Nonaktifkan cache tidak dicentang)

Anda dapat melihat bahwa respons berisi Header Cache-Control: No-cache, dan header If-modified-since cocok dengan Last-modified. ETag juga cocok.

Bukankah seharusnya Apache mengirim 304 dalam kasus itu?

EDIT

Menonaktifkan ETag dalam apache dengan

 Header  unset ETag

membuat perilaku caching lebih dapat diprediksi ...

zrz
sumber
Saya pikir Cache-Control:max-age=0menonaktifkan cache, sehingga Anda melihat Cache-Control:No-cachejawabannya.
ThoriumBR
Saya secara eksplisit mengatur Cache-Control: No-cache di konfigurasi apache saya karena dari w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1 , saya mengerti bahwa itu menyebabkan validasi ulang untuk setiap permintaan. Apakah validasi ulang menyiratkan pengiriman ulang file? Saya akan mengatakan itu harus menggunakan If-modified-since untuk menentukan apakah itu 200 atau 304.
zrz

Jawaban:

8

Tampaknya ini adalah bug lama , menjelaskan mengapa Header unset ETagada perbedaan.

Apache 2.4.0+ secara otomatis menambahkan nama metode kompresi ke ETag (seperti yang terlihat di header Anda), dan mencegah respons 304.

Versi mod_deflate terbaru mendukung DeflateAlterETag yang dapat digunakan untuk mengontrol perilaku ini:

DeflateAlterETag NoChange
Mathias R. Jessen
sumber
3
Ini benar tetapi Apache 2.4 tidak mengandung opsi itu, hanya Apache 2.5. Namun secara pribadi saya tidak menemukan ETag yang berguna karena Apache mendasarkan mereka pada tanggal modifikasi terakhir, daripada konten file. Jadi mematikan ETags kembali ke header If-Modified-Sejak, yang didasarkan pada tanggal modifikasi terakhir pula. Anda dapat mengubah ETag di Apache untuk menjadikannya berdasarkan ukuran, modifikasi terakhir dan / atau inode - dengan ukuran dan modifikasi terakhir menjadi default - tetapi, hingga mereka menambahkan opsi untuk menghitung ETag berdasarkan pada checksum konten file, itu penggunaan IMHO terbatas. Jadi saya mematikannya.
Barry Pollard
1
@ BazzaDP Itu masuk akal. 2.5 juga memiliki DeflateAlterETag Removeopsi untuk melakukan hal itu
Mathias R. Jessen
0

Yang ini menonjol dalam permintaan sebagai agak aneh:

Cache-Control:max-age=0

Namun sepertinya lebih penting, saya perhatikan bahwa konten yang dikembalikan adalah html. Apakah ini dihasilkan secara dinamis? Apache MUNGKIN mengirim respons 304, tetapi kecuali Anda menyajikan konten statis, itu bukan tugas Apache untuk melakukan panggilan itu, dan itu tergantung pada logika aplikasi Anda. Misalnya sebagian besar aplikasi php memiliki dukungan terbatas untuk hal-hal seperti itu.

Cache ujung depan dapat membantu, karena aplikasi caching dapat memeriksa waktu modifikasi, etag, dll., Tetapi hanya jika aplikasi dan header permintaan ramah terhadap cache. Misalnya aplikasi harus mengatur tajuk yang tepat untuk menunjukkan bahwa konten tersebut dapat di-cache, dan hal-hal seperti tajuk kontrol Cache dalam permintaan Anda akan meniadakan cache. Header Anda tidak terlihat ramah cache.

mc0e
sumber
File yang diminta adalah file html statis, di mana Apache mendapatkan waktu modifikasi dengan benar. (Terakhir Dimodifikasi: Sel, 14 Okt 2014 15:10:37 GMT). max-age = 0 header dalam permintaan yang dikirim oleh chrome ketika saya mengetik URL dan tekan Enter. Apakah ada karena tanggapan sebelumnya?
zrz
Saya membaca bahwa Chrome secara otomatis menambahkan Cache-Control: max-age = 0 untuk meminta (kecuali untuk pertama kali Anda memuat Chrome, ketik URL, tekan enter). Tapi itu tampaknya tidak mempengaruhi server lain (CDN mengirim 304 bahkan dengan max-age = 0 dalam permintaan).
zrz
@ zrz: membatasi caching perantara sangat berguna saat debugging, tetapi sebaliknya akan merusak kinerja. Periksa konteks apa yang Anda baca tentang apa yang chrome lakukan. Dalam hal apa yang dilakukan apache, ini cukup dapat dikonfigurasi. Kontrol cache adalah instruksi untuk cache perantara, bukan untuk server asal. Namun, apache dapat bertindak sebagai cache perantara, dan dapat dikonfigurasi untuk melakukan segala macam hal. Saya pikir jika Anda mengambil instruksi anti-caching Anda, Anda akan mendapatkan perilaku lebih seperti apa yang Anda harapkan dari server asal.
mc0e
0

Jika Anda memiliki Apache yang dikonfigurasi Cache-Control:No-cache, Apache tidak akan pernah mengirim HTTP 304 Not modifiedke klien.

Jika Anda ingin memvalidasi ulang beberapa permintaan, letakkan Cache-Control:No-cachehanya pada halaman di mana Anda membutuhkannya. Anda tidak perlu memvalidasi ulang semua sumber daya, dan Anda menghabiskan bandwidth dengan melakukannya.

ToriumBR
sumber
Saya sepertinya bingung dengan istilah "validasi ulang". Bagi saya, itu berarti memeriksa apakah itu 304. Apakah saya salah?
zrz
Anda salah. Validasi kembali adalah untuk mengirim data semua lagi ke klien dan memaksanya membaca semuanya lagi bahkan jika sudah memiliki informasi yang sama. Anda pada dasarnya menonaktifkan cache pada setiap klien.
ThoriumBR
Itu sangat menjelaskan. Hal terakhir yang saya perlu jelaskan adalah bahwa Apache mengirimkan 304 untuk beberapa sumber daya (png misalnya), sementara saya masih memiliki Cache-Control yang mengatur no-cache dalam respons dan untuk max-age = 0 dalam permintaan. Ada petunjuk?
zrz
@ThoriumBR Jika saya telah menafsirkan Anda dengan benar, kedua jawaban Anda salah di sini; no-cache (sebagai lawan dari no-store) tidak berarti "jangan cache", dan dapat mengakibatkan 304 jika konten tidak berubah. Memang OP mengharapkan ini tetapi tidak mendapatkannya karena masalah etag. harus divalidasi ulang berkaitan dengan bagaimana konten basi ditangani dan tidak selalu mengirim "data semua lagi".
Nick