Önbellek Kontrolü nedir: özel?


151

Chesseng.herokuapp.com'u ziyaret ettiğimde şöyle görünen bir yanıt başlığı alıyorum

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

ve sonra sayfayı yenilerim ve

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

bu yüzden önbelleğe alma çalışıyor gibi görünüyor. Bu önbelleğe almak için işe yarıyorsa , Expires ve Cache-Control'ün amacı nedir : max-age . Kafa karışıklığına ek olarak, sayfayı https://developers.google.com/speed/pagespeed/insights/ adresinde test ettiğimde bana "Tarayıcı önbelleğinden yararlan" diyor.


bu diyagramı kontrol edin stackoverflow.com/a/49925190/3748498
pravdomil

Yanıtlar:


78

Web sunucusu üstbilgileri içermese bile önbelleğe almanın neden çalıştığıyla ilgili sorunuza cevap vermek için:

  • Bitiş tarihi: [a date]
  • Önbellek Kontrolü: max-age =[seconds]

Sunucu, herhangi bir ara proxy'den içeriği önbelleğe almamasını istedi (yani öğe yalnızca özel bir önbellekte, yani yalnızca kendi yerel makinenizde önbelleğe alınmalıdır ):

  • Önbellek Kontrolü: özel

Ancak sunucu her türlü önbelleğe alma ipucunu eklemeyi unuttu:

  • Expires eklemeyi unuttular , böylece tarayıcı önbelleğe alınmış kopyayı o tarihe kadar kullanacağını bilir
  • Max-Age eklemeyi unuttular , böylece tarayıcı önbelleğe alınan öğenin ne kadar süreyle
  • tarayıcı koşullu bir istekte bulunabilmesi için E-Etiket eklemeyi unuttular

Ancak yanıta bir Son Değiştirilme tarihi eklediler:

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

Tarayıcı, dosyanın değiştirildiği tarihi bildiğinden, koşullu bir istek gerçekleştirebilir . Sunucudan dosyayı isteyecek, ancak sunucuya dosyayı yalnızca 2012/10/16 3:13:38 tarihinden bu yana değiştirilmişse göndermesi talimatını verecektir:

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

Sunucu isteği alır ve istemcinin halihazırda en son sürüme sahip olduğunu fark eder. İstemciyi 200 OKve ardından sayfanın içeriğini göndermek yerine, önbelleğe alınmış sürümünüzün iyi olduğunu söyler:

304 Not Modified

Tarayıcınız, sunucuya bir istek gönderme gecikmesi yaşamalı ve bir yanıt beklemeliydi, ancak statik içeriği yeniden indirmek zorunda kalmadı.

Neden Max-Age ? Neden Süresi Doluyor ?

Çünkü Last-Modified berbat.

Sunucuda Her şey vardır kendisiyle ilişkili bir tarih. Anında bir sayfa oluşturuyorsam, onunla ilişkili bir tarih yok - şimdi . Ancak, kullanıcının ana sayfayı 15 saniye boyunca önbelleğe almasına kesinlikle izin veriyorum:

200 OK
Cache-Control: max-age=15

Kullanıcı çekiçlerse F5, önbelleğe alınmış sürümü 15 saniye boyunca almaya devam edecekler. Kurumsal bir proxy ise, aynı 15 saniyelik pencerede aynı sayfaya giren 67198 kullanıcının tümü aynı içeriği alacaktır - tümü yakın önbellekten sunulur. Herkes için performans kazancı.

Eklemenin erdemi Cache-Control: max-age, tarayıcının koşullu bir istek gerçekleştirmesine bile gerek olmamasıdır .

  • yalnızca belirttiyseniz Last-Modified, tarayıcının bir istek gerçekleştirmesi If-Modified-Sinceve bir 304 Not Modifiedyanıt beklemesi gerekir
  • Eğer max-agebelirtmişseniz, tarayıcının ağ gidiş-dönüşünden zarar görmesi gerekmeyecektir; içerik doğrudan önbelleklerden çıkacak

"Cache-Control: max-age" ve "Expires" arasındaki fark

Expiresmodern (c. 1998) Cache-Control: max-agebaşlığın eski eşdeğeridir :

  • Expires: bir tarih belirlersiniz (iğrenç)
  • max-age: saniye belirtirsiniz (iyilik)
  • Ve her ikisi de belirtilirse, tarayıcı max-ageşunları kullanır :

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

1998'den sonra yazılan hiçbir web sitesi Expiresartık kullanılmamalı, onun yerine kullanılmalıdır max-age.

ETag nedir?

ETag , bir tarih olması gerekmemesi dışında Last-Modified'a benzer - sadece bir şey olması gerekir .

Veritabanından bir ürün listesi çıkarıyorsam, sunucu sonuncuyu rowversiontarih yerine ETag olarak gönderebilir :

200 OK
ETag: "247986"

ETag'im, statik bir kaynağın (ör. Resim, js, css, yazı tipi) veya önbelleğe alınmış işlenmiş sayfanın SHA1 karması olabilir (yani, Mozilla MDN wiki'nin yaptığı şey budur; son işaretlemeyi karma haline getirirler):

200 OK
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

Ve aynen Last-Modified'a dayalı bir koşullu istek durumunda olduğu gibi :

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

304 Not Modified

ETag'a göre şartlı bir talep gerçekleştirebilirim :

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

304 Not Modified

An ETagdaha üstündür Last-Modifiedçünkü dosyalar dışındaki şeyler için veya tarih kavramı olan şeyler için çalışır . Bu sadece bir


1
Harika! Bu cevap için bir ödül verdim. cache-controlYoksa ne olur ? Ve sadece Etag'a mı sahipsiniz? Yine de sunucuya karşı 'koşullu talep' yapması gerekmiyor mu? Çevrimdışıyken gördüğüm davranış, sadece önbellekten geri dönmesidir. Ancak çevrimdışıyken bu şartlı istekte bulunamaz. Yani bu, çevrimdışı kalırsanız süresiz olarak önbelleğe alınacağı anlamına mı geliyor? Bu soruyu burada ayrıntılı olarak zaten sordum . Bakabilir misin?
Honey

168
Cache-Control: private

Yanıt mesajının tamamının veya bir kısmının tek bir kullanıcı için tasarlandığını ve proxy sunucusu gibi paylaşılan bir önbellek tarafından önbelleğe alınmaması GEREKİR.

Gönderen RFC2616 bölüm 14.9.1


14
Çünkü tarayıcınız tarafından önbelleğe alındı. Yanıtın amaçlandığı tek kullanıcı sizsiniz.
Dan D.

13
Hayır, bunun nedeni Cache-Control:privateyalnızca paylaşılan önbelleklerin (proxy önbellekleri gibi) yanıtı önbelleğe almaması gerektiği anlamına gelmez.
Dan D.

5
@Trejkaz Hayır, gerçekten tek bir kullanıcı demek. Kullanıcı, önbelleğin bulunduğu kendi ana dizini olan bir hesaptır. Aynı kullanıcıya ait olan profiller önbelleklerini paylaşabilir. Bulduğunuz gibi. Ancak, farklı kullanıcılara aitse aynı bilgisayardaki iki profil, bu önbellek paylaşılan bir önbellek olarak değerlendirilmediği sürece önbelleklerini paylaşmamalıdır.
Dan D.

2
Ah, yani işletim sistemi düzeyinde kullanıcı başına. Evet, merak etmemin nedeni, Chrome'un gizli pencereleri ile gizli olmayan pencereler arasında, bunu yapmak için önbelleği kullanan, görünürdeki bir bilgi sızıntısı yüzünden.
Trejkaz

2
@didibus proxy-revalidate, proxy'lerin her erişimde her zaman yeniden doğrulama yapmasını gerektirir. Proxy'nin privateönbelleğe almasını engellediği yer.
Dan D.

21

RFC 2616, bölüm 14.9.1 :

Yanıt mesajının tamamının veya bir kısmının tek bir kullanıcıya yönelik olduğunu ve paylaşılan bir önbellek tarafından önbelleğe alınmaması GEREKİR ... Özel (paylaşılmayan) bir önbellek, yanıtı önbelleğe alabilir.


Tarayıcılar bu bilgiyi kullanabilir. Elbette, mevcut "kullanıcı" birçok anlama gelebilir: işletim sistemi kullanıcısı, tarayıcı kullanıcısı (ör. Chrome profilleri), vb. Belirtilmemiştir.

Benim için daha somut bir örnek , Cache-Control: privateproxy sunucularının (genellikle çok sayıda kullanıcısı olan) onu önbelleğe almamasıdır. Son kullanıcı içindir, başka hiç kimse için değildir.


Bilginize, RFC bunun güvenlik sağlamadığını açıkça belirtiyor. İçeriğin güvenliğini sağlamakla değil, doğru içeriği göstermekle ilgilidir.

Özel kelimesinin bu kullanımı yalnızca yanıtın nerede önbelleğe alınabileceğini kontrol eder ve mesaj içeriğinin gizliliğini garanti edemez.


5
Özel (paylaşılmayan) bir önbellek, yanıtı önbelleğe alabilir. Bu kısım anahtardır. Teşekkürler.
Oliver

0

Expires varlık üstbilgisi alanı, yanıtın bayat olarak kabul edildiği tarih / saati verir. Cache-control: maxage alanı, yanıtın eski olarak kabul edildiğinden daha büyük yaş değerini (saniye cinsinden) verir.

Yukarıda başlık alanı düşünüldüğünde, istemciye sunucuya istek gönderip göndermeyeceğine karar vermesi için bir mekanizma verir. Bazı durumlarda, istemci ayırmak için bir istek gönderir ve yanıtın yaş değeri, maksimum değerden daha büyüktür, bu, sunucunun kaynağı istemciye göndermesi gerektiği anlamına mı gelir? Belki kaynak hiç değişmedi.

Bu sorunu çözmek için, HTTP1.1 son değiştirilmiş kafa verir. Sunucu, istemciye yanıtın son değiştirilme tarihini verir. İstemci bu kaynağa ihtiyaç duyduğunda, If-Modified-Since head alanını sunucuya gönderir. Bu tarih, kaynağın değiştirilme tarihinden önceyse, sunucu kaynağı istemciye gönderecek ve 200 kodu verecek, aksi takdirde istemciye 304 kodunu döndürecektir ve bu, istemcinin önbelleğe aldığı kaynağı kullanabileceği anlamına gelir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.