Apa itu Kontrol Tembolok: pribadi?

148

Ketika saya mengunjungi chesseng.herokuapp.com saya mendapatkan tajuk respons yang mirip

Cache-Control:private
Connection:keep-alive
Content-Encoding:gzip
Content-Type:text/css
Date:Tue, 16 Oct 2012 06:37:53 GMT
Last-Modified:Tue, 16 Oct 2012 03:13:38 GMT
Status:200 OK
transfer-encoding:chunked
Vary:Accept-Encoding
X-Rack-Cache:miss

dan kemudian saya me-refresh halaman dan mendapatkan

Cache-Control:private
Connection:keep-alive
Date:Tue, 16 Oct 2012 06:20:49 GMT
Status:304 Not Modified
X-Rack-Cache:miss

jadi sepertinya caching berfungsi. Jika itu berhasil untuk caching maka apa gunanya Expires and Cache-Control: max-age . Untuk menambah kebingungan, ketika saya menguji halaman di https://developers.google.com/speed/pagespeed/insights/ itu memberitahu saya untuk "Leverage caching browser".

pengguna782220
sumber
periksa diagram ini stackoverflow.com/a/49925190/3748498
pravdomil

Jawaban:

74

Untuk menjawab pertanyaan Anda tentang mengapa caching berfungsi, meskipun server-web tidak menyertakan header:

  • Kedaluwarsa: [a date]
  • Kontrol Cache: max-age =[seconds]

Server dengan hormat meminta proksi perantara untuk tidak menembolok konten (mis. Item tersebut hanya boleh di-cache dalam cache pribadi , yaitu hanya pada mesin lokal Anda sendiri):

  • Kontrol Cache: pribadi

Tetapi server lupa untuk memasukkan segala jenis petunjuk caching:

  • mereka lupa menyertakan Kedaluwarsa , sehingga browser tahu untuk menggunakan salinan yang di-cache hingga tanggal itu
  • mereka lupa menyertakan Max-Age , sehingga browser tahu berapa lama item yang di-cache itu bagus
  • mereka lupa menyertakan E-Tag , sehingga browser dapat melakukan permintaan bersyarat

Tetapi mereka memasukkan tanggal modifikasi terakhir dalam respon:

Last-Modified: Tue, 16 Oct 2012 03:13:38 GMT

Karena browser tahu tanggal file diubah, ia dapat melakukan permintaan bersyarat . Ini akan meminta server untuk file, tetapi memerintahkan server untuk hanya mengirim file jika sudah dimodifikasi sejak 2012/10/16 3:13:38:

GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT

Server menerima permintaan, menyadari bahwa klien sudah memiliki versi terbaru. Alih-alih mengirim klien 200 OK, diikuti oleh konten halaman, alih-alih itu memberi tahu Anda bahwa versi cache Anda baik:

304 Not Modified

Peramban Anda harus mengalami keterlambatan pengiriman permintaan ke server, dan menunggu jawaban, tetapi itu memang menghemat karena harus mengunduh ulang konten statis.

Mengapa Max-Age ? Kenapa Berakhir? ?

Karena Last-Modified sucks.

Tidak semua yang ada di server memiliki tanggal yang terkait dengannya. Jika saya membuat halaman dengan cepat, tidak ada tanggal yang terkait dengannya - sekarang . Tapi saya sangat ingin membiarkan pengguna men-cache homepage selama 15 detik:

200 OK
Cache-Control: max-age=15

Jika pengguna palu F5 , mereka akan terus mendapatkan versi cache selama 15 detik. Jika itu adalah proksi perusahaan, maka semua pengguna 67198 yang memukul halaman yang sama dalam jendela 15 detik yang sama semua akan mendapatkan konten yang sama - semua disajikan dari cache yang dekat. Kinerja menang untuk semua orang.

Keunggulan dari menambahkan Cache-Control: max-ageadalah bahwa browser bahkan tidak harus melakukan permintaan bersyarat .

  • jika Anda hanya menentukan Last-Modified, browser harus melakukan permintaan If-Modified-Since, dan menonton untuk304 Not Modified respons
  • jika Anda tentukan max-age, peramban bahkan tidak harus menderita jaringan pulang-pergi; konten akan keluar dari cache

Perbedaan antara "Kontrol Tembolok: usia maks" dan "Kedaluwarsa"

Expiresadalah padanan setara dari Cache-Control: max-agetajuk modern (c. 1998) :

  • Expires: Anda menentukan tanggal (yuck)
  • max-age: Anda tentukan detik (ya ampun)
  • Dan jika keduanya ditentukan, maka browser menggunakan max-age:

    200 OK
    Cache-Control: max-age=60
    Expires: 20180403T192837 
    

Situs web apa pun yang ditulis setelah 1998 tidak boleh Expireslagi digunakan , dan sebagai gantinya digunakan max-age.

Apa itu ETag?

ETag mirip dengan Last-Modified , kecuali bahwa itu tidak harus menjadi tanggal - itu hanya harus menjadi sesuatu .

Jika saya menarik daftar produk dari database, server dapat mengirim yang terakhir rowversionsebagai ETag, bukan tanggal:

200 OK
ETag: "247986"

ETag saya dapat berupa hash SHA1 dari sumber daya statis (mis. Gambar, js, css, font), atau halaman yang di-cache di-cache (yaitu inilah yang dilakukan wiki Mozilla MDN; mereka meng-hasup markup terakhir):

200 OK
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

Dan persis seperti dalam kasus permintaan bersyarat berdasarkan Last-Modified :

GET / HTTP/1.1
If-Modified-Since: Tue, 16 Oct 2012 03:13:38 GMT

304 Not Modified

Saya dapat melakukan permintaan bersyarat berdasarkan ETag:

GET / HTTP/1.1
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"

304 Not Modified

An ETaglebih unggul daripada Last-Modifiedkarena berfungsi untuk hal-hal selain file , atau hal-hal yang memiliki gagasan tentang tanggal . Itu hanya merupakan

Ian Boyd
sumber
1
Luar biasa! Saya memberi hadiah untuk jawaban ini. Apa yang terjadi jika cache-controltidak ada? Dan Anda hanya memiliki Etag? Bukankah masih perlu membuat 'permintaan bersyarat' terhadap server? Perilaku yang saya lihat saat offline adalah ia baru saja kembali dari cache. Tetapi ketika sedang offline itu tidak dapat membuat permintaan bersyarat itu. Jadi apakah itu berarti jika itu akan disimpan tanpa batas jika Anda tetap offline? Saya sudah menanyakan pertanyaan ini secara rinci di sini . Bisakah Anda melihatnya?
Sayang
167
Cache-Control: private

Menunjukkan bahwa semua atau sebagian dari pesan respons ditujukan untuk satu pengguna dan TIDAK HARUS di-cache oleh cache bersama, seperti server proxy.

Dari RFC2616 bagian 14.9.1

Dan D.
sumber
14
Karena itu di-cache oleh browser Anda. Anda adalah pengguna tunggal yang responsnya dimaksudkan.
Dan D.
13
Tidak, ini bukan karena Cache-Control:privatehanya menyatakan bahwa cache bersama (seperti cache proxy) tidak boleh menembolokkan respons.
Dan D.
5
@Trejkaz Tidak, itu benar-benar berarti satu pengguna. Pengguna adalah akun yang memiliki direktori home sendiri di mana cache berada. Profil-profil yang dimiliki oleh pengguna yang sama dapat membagikan cache mereka. Seperti yang Anda temukan. Tetapi dua profil di komputer yang sama jika dimiliki oleh pengguna yang berbeda tidak boleh berbagi cache, kecuali jika cache itu diperlakukan sebagai cache bersama.
Dan D.
2
Ah, jadi itu per-pengguna-di-tingkat-OS. Ya, alasan saya bertanya-tanya adalah karena kebocoran informasi yang jelas antara jendela penyamaran Chrome dan yang bukan-penyamaran, yang menggunakan cache untuk melakukannya.
Trejkaz
2
@idibus proxy-revalidatemengharuskan proxy selalu memvalidasi ulang pada setiap akses. Dimana privatemencegah proxy dari caching.
Dan D.
20

RFC 2616, bagian 14.9.1 :

Mengindikasikan bahwa semua atau sebagian dari pesan respons ditujukan untuk satu pengguna dan TIDAK HARUS di-cache oleh cache yang dibagikan ... Cache pribadi (yang tidak dibagikan) MUNGKIN cache respon.


Browser dapat menggunakan informasi ini. Tentu saja, "pengguna" saat ini dapat berarti banyak hal: pengguna OS, pengguna browser (misalnya profil Chrome), dll. Ini tidak ditentukan.

Bagi saya, contoh yang lebih konkret dari Cache-Control: privateadalah bahwa server proxy (yang biasanya memiliki banyak pengguna) tidak akan cache itu. Ini dimaksudkan untuk pengguna akhir, dan tidak ada orang lain.


FYI, RFC menjelaskan bahwa ini tidak memberikan keamanan. Ini tentang menunjukkan konten yang benar, bukan mengamankan konten.

Penggunaan kata pribadi ini hanya mengontrol di mana respons mungkin di-cache, dan tidak dapat memastikan privasi konten pesan.

Paul Draper
sumber
5
Cache pribadi (tidak dibagi) MUNGKIN cache tanggapan. Bagian ini adalah kuncinya. Terima kasih.
Oliver
0

Bidang header-entitas Kedaluwarsa memberikan tanggal / waktu setelah respons dianggap basi. Kontrol cache: bidang maks. Memberi nilai usia (dalam detik) lebih besar daripada respons yang dianggap basi.

Meskipun bidang header di atas memberikan mekanisme kepada klien untuk memutuskan apakah akan mengirim permintaan ke server. Dalam beberapa kondisi, klien mengirim permintaan untuk memutuskan dan nilai usia respons lebih besar daripada nilai maksimal, dosis itu berarti server perlu mengirim sumber daya ke klien? Mungkin sumber dayanya tidak pernah berubah.

Untuk mengatasi masalah ini, HTTP1.1 memberikan head yang terakhir dimodifikasi. Server memberikan tanggal respons terakhir yang diubah ke klien. Ketika klien membutuhkan sumber daya ini, ia akan mengirimkan bidang kepala If-Modified-Sejak ke server. Jika tanggal ini sebelum tanggal modifikasi sumber daya, server akan mengirimkan sumber daya ke klien dan memberikan 200 kode. Jika tidak, ia akan mengembalikan 304 kode ke klien dan ini berarti klien dapat menggunakan sumber daya yang di-cache.

Lin. Ya
sumber