Bagaimana mencegah cache Browser untuk situs php

121

Saya memiliki situs php yang berjalan di server cloud. Kapan pun saya menambahkan file baru css, js, atau gambar, browser memuat file js, css, dan gambar lama yang sama yang disimpan dalam cache.

Situs saya memiliki doctype dan meta tag seperti di bawah ini

<!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)">

Karena doctype dan kode meta di atas, saya memuat file yang sama yang di-cache di browser, bukan yang baru

ArrayOutOfBound
sumber
No Cache in all Browsers. Anda juga dapat melakukan? RandomGeneratedNumber pada file yang tidak ingin di-cache.
Kodemon
2
Anda mungkin tidak ingin menonaktifkan cache sepenuhnya untuk gambar / js / css: stackoverflow.com/questions/4206224/…
FoolishSeth
Menahan godaan untuk necro, tapi tolong, siapa pun yang mempertimbangkan ini: berhenti. Belajar untuk mengontrol dan menggunakan caching, jangan hanya menonaktifkannya secara membabi buta karena satu episode yang tidak nyaman. Baca bab tentang Caching dari HTTP The Definitive Guide - buku ini (dan RFC) harus menjadi bacaan wajib, dengan tes. Pelajari cara menentukan Last-Modified, tanggapi If-Modified-Sejak, dan gunakan identifikasi ETag. Kemudian ketika aset diperbarui, browser akan diinformasikan ketika 304 menjadi 200 sekali lagi.
amcgregor

Jawaban:

283

coba ini

<?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");
?>
Codesen
sumber
6
Kecuali untuk "max-age = 0", itu adalah header yang dikirim oleh PHP tanpa menentukan hal di atas dalam instalasi saya .. Tampaknya PHP mencoba mencegah cache browser secara default ...
fast-reflexes
1
Saya memiliki plugin WordPress yang mengirimkan tema alternatif ke versi lama Internet Explorer dan itu tersandung parah pada beberapa sistem cache. Posting ini muncul di pencarian Google pertama saya. Permainan yang bagus.
Imperatif
3
Ingatlah bahwa ini tidak dapat disematkan di dalam html; ini harus berada di bagian paling atas halaman.
Hunter S
9
Catatan: Jika Anda menggunakan session_start()setelahnya, ini akan menimpa header Anda dengan Cache-Control: private, max-age=10800, pre-check=10800karena 180 menit adalah nilai default session.cache_expire. Jika Anda tidak dapat menghindari memulai sesi, tetapi Anda perlu menonaktifkan penggunaan cache session_cache_limiter('private');session_cache_expire(0);.
mgutt
2
@thdoan Parameter kedua dari headerfungsi adalah boolean untuk diganti . Parameter ganti opsional menunjukkan apakah header harus menggantikan header serupa sebelumnya, atau menambahkan header kedua dari jenis yang sama.
mrReiha
36

Di sini, jika Anda ingin mengontrolnya melalui HTML: lakukan seperti di bawah ini Opsi 1:

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

Dan jika Anda ingin mengontrolnya melalui PHP: lakukan seperti di bawah ini Opsi 2:

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');

DAN Opsi 2 SELALU LEBIH BAIK untuk menghindari masalah cache berbasis proxy.

Ritesh Aryal
sumber
10

Anda dapat mencoba ini:

    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");

Semoga membantu mencegah Cache, jika ada!

Aakanksha
sumber
Ini hanya berkaitan dengan cache file HTML, bukan? Dan tidak ada hubungannya dengan eTag? Terima kasih!
Sam Levin
4
baris pertama saja sudah cukup sempurna. Baris ke-5 sebenarnya salah dan tidak ada hubungannya dengan respons server (ini adalah header permintaan). baris keenam tidak akan berpengaruh apa pun. saya bisa melanjutkan ...
The Surrican
Pendekatan senapan: lempar semuanya ke dinding, semoga ada sesuatu yang menempel. Sesuai komentar saya tentang pertanyaan itu sendiri, saya sangat merekomendasikan untuk mengambil salinan HTTP: Panduan Definitif dan membaca bab tentang Caching. Juga RFC, tetapi membacanya adalah keterampilan yang berbeda. ("Connection: close" adalah foot-shot lucu untuk disertakan, menonaktifkan pipelining permintaan yang efisien, atau tidak akan melakukan apa pun, tetapi saya curiga PHP mungkin benar-benar membiarkannya masuk.)
amcgregor
7

Saya mengalami masalah dengan menyimpan file css saya. Menetapkan header di PHP tidak membantu saya (mungkin karena header perlu disetel di file stylesheet alih-alih halaman yang menautkannya?).

Saya menemukan solusinya di halaman ini: https://css-tricks.com/can-we-prevent-css-caching/

Solusinya:

Tambahkan stempel waktu sebagai bagian kueri dari URI untuk file yang ditautkan.
(Dapat digunakan untuk css, js, gambar dll.)

Untuk pengembangan:

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

Untuk produksi (di mana sebagian besar cache adalah hal yang baik):

<link rel="stylesheet" type="text/css" href="style.css?version=3.2">
(dan tulis ulang secara manual jika diperlukan)

Atau kombinasi keduanya:

<?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') : ""; ?>">

EDIT:

Atau kombinasi yang lebih cantik dari keduanya:

<?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(); ?>">
Lukas
sumber
Versi sewenang-wenang, stempel waktu saat ini (mengalahkan caching seluruhnya)… tetapi bukan satu hal yang benar-benar masuk akal dan berfungsi, terlepas dari tanda "debugging" atau tidak. Mengapa Anda tidak menggunakan mtime file yang sebenarnya? Maka Anda benar-benar tidak perlu memperbarui PHP, dan cache tidak akan menjadi benar-benar tidak berguna. Atau cukup kirimkan statika Anda dengan server HTTP yang dikonfigurasi dengan benar seperti Nginx atau Apache yang menetapkan Last-Modified dan ETag yang tepat. Demikian pula, jenis tanda "debugging" itu sudah ada… di browser. (Nonaktifkan cache, segarkan tanpa cache, kosongkan cache,…)
amcgregor
5

Mencegah cache browser bukanlah ide yang baik tergantung pada kasusnya. Mencari solusi saya menemukan solusi seperti ini:

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

Masalahnya di sini adalah jika file ditimpa selama pembaruan di server, yang merupakan skenario saya, cache diabaikan karena stempel waktu diubah meskipun konten file sama.

Saya menggunakan solusi ini untuk memaksa browser mengunduh aset hanya jika kontennya diubah:

<link rel="stylesheet" type="text/css" href="meu.css?v=<?=hash_file('md5', $file);?>">
umat manusia
sumber
Astaga! Ini akan sangat buruk bagi kinerja dan skalabilitas untuk selalu memuat semua file CSS / JS Anda di utas utama untuk memeriksa ukuran / hashnya.
Dalin
@Dalin Sebelum Anda menangis air mata Gentoo ricer (distro Linux yang dikenal dengan "berjalan cepat" karena terlalu banyak dikompilasi dari sumber dan arsitektur-tuned) saya akan statmenelepon. Tanpa cache sistem file, 16ns, puncak? Dengan cache, andal <8ns. Nano. Dan di sistem saya, MD5 dapat memproses 754 MiB / s tanpa berkedip. ( openssl speed md5) Gabungan, file CSS 100 KB akan memiliki overhead tambahan gabungan… 129µs (mikrodetik, 0,1295 md) + 8ns (yang tidak berkontribusi secara berarti ke angka akhir) = 129µs.
amcgregor
Setelah dipertimbangkan lebih lanjut, saya terkejut bahwa satu-satunya jawaban yang "benar" (dengan beban pemeliharaan terendah, perilaku paling akurat / dapat diandalkan) adalah yang paling sedikit dipilih, dan ditolak dalam satu komentar dengan alasan yang tipis dan tidak realistis.
amcgregor
Anda dan saya mungkin bekerja di situs web yang berbeda. Tapi saya mendukung komentar saya. Jika ada lusinan utas bersamaan yang mengirimkan halaman web kapan saja, maka menurut saya ada opsi yang lebih baik sehingga Anda bahkan tidak perlu mempertanyakan apakah itu dapat diskalakan. hash_file('md5', $deployment_counter)atau hash_file('md5', $cache_clear_counter)yang pertama terlintas dalam pikiran.
Dalin