Php sitesi için tarayıcı önbelleği nasıl engellenir


121

Bulut sunucusunda çalışan bir php sitem var. Yeni dosyalar css, js veya resimler eklediğimde tarayıcı önbellekte depolanan aynı eski js, css ve görüntü dosyalarını yüklüyor.

Sitemin aşağıdaki gibi bir belge türü ve meta etiketi var

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

  <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
  <meta http-equiv="Page-Enter" content="blendTrans(Duration=1.0)">
  <meta http-equiv="Page-Exit" content="blendTrans(Duration=1.0)">
  <meta http-equiv="Site-Enter" content="blendTrans(Duration=1.0)">
  <meta http-equiv="Site-Exit" content="blendTrans(Duration=1.0)">

Yukarıdaki belge türü ve meta kod nedeniyle, yenisi yerine tarayıcıda önbelleğe alınmış aynı dosyaları yüklüyorum


No Cache in all Browsers. Ayrıca önbelleğe alınmasını istemediğiniz dosyalara bir? RandomGeneratedNumber da yapabilirsiniz.
Kodemon

2
Muhtemelen images / js / css için önbelleği tamamen devre dışı bırakmak istemezsiniz: stackoverflow.com/questions/4206224/…
FoolishSeth

Necro çekiciliğine direndi, ama lütfen bunu düşünen herkes: dur. Önbelleğe almayı kontrol etmeyi ve kullanmayı öğrenin, uygunsuz bir bölüm nedeniyle sadece körü körüne devre dışı bırakmayın. Kesin Kılavuz - HTTP'den Önbelleğe Alma hakkındaki bölümü okuyun - bu kitap (ve RFC'ler) bir testle birlikte zorunlu okuma olmalıdır. Last-Modified'ı nasıl belirleyeceğinizi, If-Modified-Since'e nasıl yanıt vereceğinizi ve ETag kimliğini nasıl kullanacağınızı öğrenin. Ardından varlık güncellendiğinde, bu 304 tekrar 200 olduğunda tarayıcılar bilgilendirilecektir.
amcgregor

Yanıtlar:


283

bunu dene

<?php

header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
?>

6
"Max-age = 0" dışında, bunlar PHP tarafından kurulumumda yukarıdakileri belirtmeden gönderilen üstbilgilerdir .. Görünüşe göre PHP varsayılan olarak tarayıcı önbelleğe almayı engellemeye çalışıyor ...
hızlı refleksler

1
Internet Explorer'ın eski sürümlerine alternatif bir tema gönderen bir WordPress eklentim var ve bazı önbellekleme sistemlerinde kötü bir şekilde takılıyordu. Bu gönderi ilk Google aramamda geldi. Güzel oynadı.
Zorunlu

3
Bunun html'nin içine gömülemeyeceğini unutmayın; bu sayfanın en üstünde olmalıdır.
Hunter S

9
Not: Daha session_start()sonra kullanırsanız , başlığınızın üzerine yazacaktır Cache-Control: private, max-age=10800, pre-check=10800çünkü 180 dakika varsayılan değerdir session.cache_expire. Oturumu başlatmaktan kaçınamıyorsanız, ancak önbellek kullanımını devre dışı bırakmanız gerekiyorsa session_cache_limiter('private');session_cache_expire(0);.
mgutt

2
@thdoan ikinci parametre headerişlevi a, boolean için yerine . İsteğe bağlı değiştirme parametresi, başlığın önceki benzer bir başlığın yerini alması veya aynı türden ikinci bir başlık eklemesi gerektiğini belirtir.
mrReiha

36

Burada, HTML ile kontrol etmek istiyorsanız: 1. Seçeneği aşağıdaki gibi yapın :

<meta http-equiv="expires" content="Sun, 01 Jan 2014 00:00:00 GMT"/>
<meta http-equiv="pragma" content="no-cache" />

Ve PHP aracılığıyla kontrol etmek istiyorsanız: Seçenek 2'yi aşağıdaki gibi yapın :

header('Expires: Sun, 01 Jan 2014 00:00:00 GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', FALSE);
header('Pragma: no-cache');

VE Seçenek 2 , proxy tabanlı önbelleğe alma sorununu önlemek için DAİMA DAHA İYİDİR.


10

Bunu deneyebilirsiniz:

    header("Expires: Tue, 03 Jul 2001 06:00:00 GMT");
    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
    header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
    header("Cache-Control: post-check=0, pre-check=0", false);
    header("Pragma: no-cache");
    header("Connection: close");

Varsa, Cache'i önlemeye yardımcı olacağını umuyoruz!


Bu sadece HTML dosyalarının önbelleğe alınmasıyla ilgilidir, değil mi? ETag ile ilgisi yok mu? Teşekkürler!
Sam Levin

4
sadece ilk satır mükemmel şekilde yeterli olmalıdır. 5. satır aslında tamamen yanlıştır ve bir sunucu yanıtında ilgisi yoktur (bu bir istek başlığıdır). altıncı satırın hiçbir etkisi olmayacak. devam edebilirim ...
The Surrican

Av tüfeği yaklaşımı: Her şeyi duvara fırlatın, bir şeyin yapışmasını umun. Sorunun kendisiyle ilgili yorumuma göre, HTTP: The Definitive Guide'ın bir kopyasını almanızı ve Önbelleğe Alma hakkındaki bölümü okumanızı şiddetle tavsiye edebilirim . Ayrıca RFC'ler, ancak bunları okumak ayrı bir beceridir. ("Bağlantı: kapat", isteklerin verimli bir şekilde sıralanmasını devre dışı bırakmak veya hiçbir şey yapmamak için komik bir ayak
vuruşudur

7

Css dosyalarımı önbelleğe alma konusunda sorun yaşadım. PHP'de üstbilgiler ayarlamak bana yardımcı olmadı (belki de başlıkların ona bağlanan sayfa yerine stil sayfası dosyasında ayarlanması gerektiğinden?).

Çözümü bu sayfada buldum: https://css-tricks.com/can-we-prevent-css-caching/

Çözüm:

Bağlantılı dosya için URI'nin sorgu parçası olarak zaman damgası ekleyin.
(Css, js, resimler vb. İçin kullanılabilir.)

Geliştirme için:

<link rel="stylesheet" href="style.css?<?php echo date('Y-m-d_H:i:s'); ?>">

Üretim için (önbelleğe almanın çoğunlukla iyi bir şey olduğu durumlarda):

<link rel="stylesheet" type="text/css" href="style.css?version=3.2">
(ve gerektiğinde manuel olarak yeniden yazın)

Veya bu ikisinin kombinasyonu:

<?php
    define( "DEBUGGING", true ); // or false in production enviroment
?>
<!-- ... -->
<link rel="stylesheet" type="text/css" href="style.css?version=3.2<?php echo (DEBUGGING) ? date('_Y-m-d_H:i:s') : ""; ?>">

DÜZENLE:

Veya bu ikisinin daha güzel kombinasyonu:

<?php
    // Init
    define( "DEBUGGING", true ); // or false in production enviroment
    // Functions
    function get_cache_prevent_string( $always = false ) {
        return (DEBUGGING || $always) ? date('_Y-m-d_H:i:s') : "";
    }
?>
<!-- ... -->
<link rel="stylesheet" type="text/css" href="style.css?version=3.2<?php echo get_cache_prevent_string(); ?>">

Rasgele sürümler, mevcut zaman damgaları (önbelleğe almayı tamamen ortadan kaldıran)… ama "hata ayıklama" işaretine bakılmaksızın, aslında mantıklı ve işe yarayan tek şey değil. Neden dosyanın gerçek mtime'ını kullanmıyorsun? Öyleyse, kelimenin tam anlamıyla hiçbir zaman PHP'yi güncellemenize gerek kalmaz ve önbellekler tamamen ve fevkalade faydasız olmaz. Veya statiğinizi, uygun bir Last-Modified ve ETag ayarlayan Nginx veya Apache gibi düzgün yapılandırılmış bir HTTP sunucusuyla gönderin. Benzer şekilde, bu tür bir "hata ayıklama" bayrağı tarayıcıda zaten mevcuttur. (Önbellekleri devre dışı bırakın, önbellek olmadan yenileyin, önbellekleri boşaltın,…)
amcgregor

5

Tarayıcı önbelleğini önlemek, duruma bağlı olarak iyi bir fikir değildir. Bir çözüm arıyorum, bunun gibi çözümler buldum:

<link rel="stylesheet" type="text/css" href="meu.css?v=<?=filemtime($file);?>">

Buradaki sorun, sunucudaki bir güncelleme sırasında dosyanın üzerine yazılırsa, ki benim senaryom bu, dosyanın içeriği aynı olsa bile zaman damgası değiştirildiği için önbellek yok sayılır.

Bu çözümü, tarayıcıyı yalnızca içeriği değiştirilirse varlıkları indirmeye zorlamak için kullanıyorum:

<link rel="stylesheet" type="text/css" href="meu.css?v=<?=hash_file('md5', $file);?>">

Olmadı! Bu, performans ve ölçeklenebilirliğin boyutlarını / karmalarını kontrol etmek için ana iş parçacığındaki tüm CSS / JS dosyalarınızı her zaman yüklüyor olması açısından korkunç olur.
Dalin

@Dalin Gentoo Ricer'ın gözyaşlarını ağlamadan önce (kaynaktan aşırı derecede derlenmiş ve mimari ayarlı olarak "hızlı gitme" ile tanınan bir Linux dağıtımı) bir statçağrı alırdım . Dosya sistemi önbelleği olmadan, 16ns, tops? Önbellek ile güvenilir <8ns. Nanosaniye. Ve benim sistemimde MD5, 754 MiB / sn'yi yanıp sönmeden işleyebilir. ( openssl speed md5) Birleştirildiğinde, 100KB'lik bir CSS dosyasının toplam ek yükü ... 129µs (mikrosaniye, 0.1295ms) + 8ns (son sayıya anlamlı bir şekilde katkıda bulunmaz) = 129µs olacaktır.
amcgregor

Daha fazla düşündükten sonra, tek "doğru" cevabın (en düşük bakım yükü, en doğru / güvenilir davranış) hem en az oylanan hem de böylesine dayanıksız ve gerçekçi olmayan gerekçelerle tek bir yorumda reddedildiği beni uçuruyor.
amcgregor

Muhtemelen farklı web sitelerinde çalışıyoruz. Ama yorumuma katılıyorum. Herhangi bir zamanda web sayfalarını sunan düzinelerce eşzamanlı iş parçacığı varsa, ölçeklenebilir olup olmadığını sorgulamanıza gerek kalmayacak daha iyi seçenekler olduğunu düşünüyorum. hash_file('md5', $deployment_counter)veya hash_file('md5', $cache_clear_counter)akla ilk gelenler.
Dalin
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.