Saya perhatikan bahwa beberapa browser (khususnya, Firefox dan Opera) sangat bersemangat dalam menggunakan salinan file .css dan .js yang di-cache , bahkan di antara sesi browser. Ini mengarah ke masalah ketika Anda memperbarui salah satu file ini tetapi browser pengguna terus menggunakan salinan yang di-cache.
Pertanyaannya adalah: apa cara paling elegan untuk memaksa browser pengguna memuat ulang file ketika telah berubah?
Idealnya, solusinya tidak akan memaksa browser untuk memuat ulang file pada setiap kunjungan ke halaman. Saya akan memposting solusi saya sendiri sebagai jawaban, tetapi saya ingin tahu apakah ada yang punya solusi yang lebih baik dan saya akan membiarkan suara Anda memutuskan.
Perbarui:
Setelah membiarkan diskusi di sini untuk sementara waktu, saya telah menemukan saran John Millikin dan da5id berguna. Ternyata ada istilah untuk ini: versi otomatis .
Saya telah memposting jawaban baru di bawah ini yang merupakan kombinasi dari solusi asli saya dan saran John.
Gagasan lain yang disarankan oleh SCdF adalah menambahkan string kueri palsu ke file. (Beberapa kode Python untuk secara otomatis menggunakan stempel waktu sebagai string kueri palsu dikirim oleh pi .). Namun, ada beberapa diskusi tentang apakah browser akan men-cache file dengan string kueri. (Ingat, kami ingin browser untuk men-cache file dan menggunakannya pada kunjungan berikutnya. Kami hanya ingin mengambil file itu lagi ketika sudah berubah.)
Karena tidak jelas apa yang terjadi dengan string kueri palsu, saya tidak menerima jawaban itu.
ExpiresActive On ExpiresDefault "modification"
.iframe.contentWindow.location.reload(true)
. Lihat metode (4) dari stackoverflow.com/a/22429796/999120 - itu tentang gambar, tetapi hal yang sama berlaku.Jawaban:
Pembaruan: Ditulis ulang untuk memasukkan saran dari John Millikin dan da5id . Solusi ini ditulis dalam PHP, tetapi harus dengan mudah diadaptasi ke bahasa lain.
Pembaruan 2: Memasukkan komentar dari Nick Johnson bahwa
.htaccess
regex asli dapat menyebabkan masalah dengan file sepertijson-1.3.js
. Solusi adalah dengan hanya menulis ulang jika ada tepat 10 digit di akhir. (Karena 10 digit mencakup semua cap waktu dari 9/9/2001 hingga 11/20/2286.)Pertama, kami menggunakan aturan penulisan ulang berikut di .htaccess:
Sekarang, kita menulis fungsi PHP berikut:
Sekarang, di mana pun Anda memasukkan CSS Anda, ubahlah dari ini:
Untuk ini:
Dengan cara ini, Anda tidak perlu mengubah tag tautan lagi, dan pengguna akan selalu melihat CSS terbaru. Browser akan dapat melakukan cache file CSS, tetapi ketika Anda membuat perubahan pada CSS Anda browser akan melihat ini sebagai URL baru, sehingga tidak akan menggunakan salinan cache.
Ini juga dapat bekerja dengan gambar, favicon, dan JavaScript. Pada dasarnya segala sesuatu yang tidak dihasilkan secara dinamis.
sumber
file_exists
cek pertama benar-benar diperlukan?filemtime
akan mengembalikan false pada kegagalan, jadi mengapa tidak hanya menetapkan nilai filemtime ke variabel dan memeriksa apakah itu salah sebelum mengganti nama file? Itu akan mengurangi satu operasi file yang tidak perlu yang benar-benar akan bertambah.Teknik Sisi Klien Sederhana
Secara umum, caching itu baik. Jadi ada beberapa teknik, tergantung pada apakah Anda memperbaiki masalah sendiri saat Anda mengembangkan situs web, atau apakah Anda mencoba mengendalikan cache di lingkungan produksi.
Pengunjung umum ke situs web Anda tidak akan memiliki pengalaman yang sama dengan yang Anda alami saat mengembangkan situs. Karena rata-rata pengunjung datang ke situs lebih jarang (mungkin hanya beberapa kali setiap bulan, kecuali Anda seorang Google atau Jaringan hi5), maka mereka cenderung memiliki file Anda dalam cache, dan itu mungkin cukup. Jika Anda ingin memaksakan versi baru ke browser, Anda selalu dapat menambahkan string kueri ke permintaan, dan menambahkan nomor versi ketika Anda membuat perubahan besar:
Ini akan memastikan bahwa semua orang mendapatkan file baru. Ini berfungsi karena browser melihat URL file untuk menentukan apakah ia memiliki salinan dalam cache. Jika server Anda tidak diatur untuk melakukan apa pun dengan string kueri, itu akan diabaikan, tetapi nama akan terlihat seperti file baru untuk browser.
Di sisi lain, jika Anda mengembangkan situs web, Anda tidak ingin mengubah nomor versi setiap kali Anda menyimpan perubahan ke versi pengembangan Anda. Itu akan membosankan.
Jadi saat Anda mengembangkan situs Anda, trik yang bagus adalah menghasilkan parameter string kueri secara otomatis:
Menambahkan string kueri ke permintaan adalah cara yang baik untuk versi sumber daya, tetapi untuk situs web sederhana ini mungkin tidak perlu. Dan ingat, caching adalah hal yang baik.
Perlu juga dicatat bahwa browser tidak selalu pelit untuk menyimpan file dalam cache. Browser memiliki kebijakan untuk hal semacam ini, dan mereka biasanya bermain sesuai aturan yang ditetapkan dalam spesifikasi HTTP. Saat browser mengajukan permintaan ke server, bagian dari responsnya adalah header EXPIRES .. tanggal yang memberitahu browser berapa lama harus disimpan dalam cache. Saat berikutnya browser menemukan permintaan untuk file yang sama, ia melihat bahwa ia memiliki salinan dalam cache dan melihat ke tanggal kedaluwarsa untuk memutuskan apakah itu harus digunakan.
Jadi percaya atau tidak, sebenarnya server Anda yang membuat cache browser itu begitu gigih. Anda dapat menyesuaikan pengaturan server Anda dan mengubah header KEDATANGAN, tetapi teknik kecil yang saya tulis di atas mungkin merupakan cara yang jauh lebih sederhana bagi Anda untuk melakukannya. Karena caching itu baik, Anda biasanya ingin mengatur tanggal itu jauh di masa depan ("Header Masa Depan Jauh Jauh"), dan menggunakan teknik yang dijelaskan di atas untuk memaksakan perubahan.
Jika Anda tertarik pada info lebih lanjut tentang HTTP atau bagaimana permintaan ini dibuat, buku yang bagus adalah "Situs Web Kinerja Tinggi" oleh Steve Souders. Ini adalah pengantar yang sangat bagus untuk subjek ini.
sumber
<link href='myCss.css?dev=14141'...>
Plugin mod_pagespeed Google untuk apache akan melakukan versi otomatis untuk Anda. Sangat apik.
Ini mem-parsing HTML saat keluar dari server web (bekerja dengan PHP, rails, python, HTML statis - apa saja) dan menulis ulang tautan ke CSS, JS, file gambar sehingga mereka memasukkan kode id. Ini menyajikan file di URL yang dimodifikasi dengan kontrol cache yang sangat panjang. Ketika file berubah, itu secara otomatis mengubah URL sehingga browser harus mengambilnya kembali. Ini pada dasarnya hanya berfungsi, tanpa ada perubahan pada kode Anda. Bahkan akan memperkecil kode Anda di jalan keluar juga.
sumber
Alih-alih mengubah versi secara manual, saya akan merekomendasikan Anda menggunakan hash MD5 dari file CSS yang sebenarnya.
Jadi URL Anda akan seperti itu
Anda masih dapat menggunakan aturan penulisan ulang untuk menghapus hash, tetapi keuntungannya adalah sekarang Anda dapat mengatur kebijakan cache Anda menjadi "cache selamanya", karena jika URL-nya sama, itu berarti bahwa file tidak berubah.
Anda kemudian dapat menulis skrip shell sederhana yang akan menghitung hash file dan memperbarui tag Anda (Anda mungkin ingin memindahkannya ke file terpisah untuk dimasukkan).
Cukup jalankan skrip itu setiap kali CSS berubah dan Anda baik-baik saja. Browser HANYA akan memuat ulang file Anda ketika mereka diubah. Jika Anda mengedit dan membatalkannya, tidak ada kesulitan untuk menentukan versi yang harus Anda kembalikan agar pengunjung Anda tidak mengunduh ulang.
sumber
Tidak yakin mengapa kalian mengambil begitu banyak rasa sakit untuk menerapkan solusi ini.
Yang perlu Anda lakukan jika mendapatkan cap waktu yang dimodifikasi file dan menambahkannya sebagai querystring ke file
Dalam PHP saya akan melakukannya sebagai:
filemtime adalah fungsi PHP yang mengembalikan stempel waktu yang dimodifikasi file.
sumber
mycss.css?1234567890
.<link rel="stylesheet" href="mycss.css?<?php echo filemtime('mycss.css') ?>"/>
berjaga-jaga jika beberapa argumen di utas ini tentang caching URL dengan variabel GET (dalam format yang disarankan) sudah benar?ver=
siapa yang tahu!Anda bisa meletakkan
?foo=1234
di akhir impor css / js Anda, mengubah 1234 menjadi apa pun yang Anda suka. Lihat sumber html SO untuk contoh.Gagasan di sana adalah bahwa? parameter dibuang / diabaikan pada permintaan dan Anda dapat mengubah nomor itu ketika Anda meluncurkan versi baru.
Catatan: Ada beberapa argumen terkait dengan persis bagaimana ini mempengaruhi caching. Saya percaya intinya adalah bahwa GET permintaan, dengan atau tanpa parameter harus dapat di-cachable, sehingga solusi di atas harus bekerja.
Namun, itu tergantung pada server web untuk memutuskan apakah ia ingin mematuhi bagian dari spesifikasi dan browser yang digunakan pengguna, karena itu bisa langsung saja melanjutkan dan meminta versi yang baru.
sumber
Saya pernah mendengar ini disebut "versi otomatis". Metode yang paling umum adalah memasukkan mtime file statis di suatu tempat di URL, dan menghapusnya menggunakan penulisan ulang penangan atau URL confs:
Lihat juga:
sumber
30 atau lebih jawaban yang ada adalah saran bagus untuk situs web sekitar tahun 2008. Namun, ketika datang ke aplikasi modern, satu halaman (SPA), mungkin sudah saatnya untuk memikirkan kembali beberapa asumsi mendasar ... khususnya gagasan bahwa diinginkan untuk server web untuk hanya melayani versi tunggal, terbaru dari suatu mengajukan.
Bayangkan Anda adalah pengguna yang memiliki M versi SPA yang dimuat ke browser Anda:
/some.template
/some.template
- apakah Anda ingin mengembalikan versi M atau N dari templat?Jika format
/some.template
berubah antara versi M dan N (atau file diubah namanya atau apa pun), Anda mungkin tidak ingin versi N dari template dikirim ke browser yang menjalankan versi M lama dari pengurai . †Aplikasi web mengalami masalah ini ketika dua kondisi terpenuhi:
Setelah aplikasi Anda perlu menyajikan beberapa versi secara paralel, menyelesaikan caching dan "memuat ulang" menjadi sepele:
/v<release_tag_1>/…files…
,/v<release_tag_2>/…files…
<script>
dan<link>
tag, dll. Untuk menunjuk ke file itu di salah satu dir versiLangkah terakhir itu terdengar rumit, karena bisa memerlukan memanggil pembuat URL untuk setiap URL di sisi server atau kode sisi klien Anda. Atau Anda bisa memanfaatkan
<base>
tag dengan cerdas dan mengubah versi saat ini di satu tempat.† Salah satu cara untuk mengatasi hal ini adalah bersikap agresif memaksa browser untuk memuat ulang semuanya saat versi baru dirilis. Tetapi demi membiarkan semua operasi dalam proses untuk menyelesaikan, mungkin masih paling mudah untuk mendukung setidaknya dua versi secara paralel: v-current dan v-before.
sumber
base
tag! Adapun mendukung kode lama: ini tidak selalu merupakan kemungkinan, juga tidak selalu merupakan ide yang baik. Versi kode baru dapat mendukung pemutusan perubahan pada bagian lain aplikasi atau mungkin melibatkan perbaikan darurat, patch kerentanan, dan sebagainya. Saya belum menerapkan strategi ini sendiri, tetapi saya selalu merasa arsitektur secara keseluruhan harus memungkinkan penyebaran untuk menandai versi lamaobsolete
dan memaksakan pemuatan ulang saat lain kali panggilan tidak sinkron dibuat (atau hanya dengan paksa menonaktifkan semua sesi melalui WebSockets. ).Jangan gunakan foo.css? Versi = 1! Peramban tidak seharusnya menembolok URL dengan variabel GET. Menurut http://www.thinkvitamin.com/features/webapps/serving-javascript-fast , meskipun IE dan Firefox mengabaikannya, Opera dan Safari tidak! Sebaliknya, gunakan foo.v1234.css, dan gunakan aturan penulisan ulang untuk menghapus nomor versi.
sumber
Dalam Laravel (PHP) kita dapat melakukannya dengan mengikuti cara yang jelas dan elegan (menggunakan cap waktu modifikasi file):
Dan serupa untuk CSS
Contoh html output (
filemtime
waktu pengembalian sebagai cap waktu Unix )sumber
Aturan RewriteRule membutuhkan pembaruan kecil untuk file js atau css yang mengandung versi notasi titik di bagian akhir. Misalnya json-1.3.js.
Saya menambahkan kelas negasi titik [^.] Ke regex jadi .number. diabaikan.
sumber
^(.*)\.[\d]{10}\.(css|js)$ $1.$2
[^.]
sini. Juga, tidak ada manfaatnya menulis\d
di dalam kelas karakter -\d+
akan melakukan hal yang sama. Seperti yang diposting, pola Anda akan cocok dengan sejumlah karakter (dengan rakus), kemudian titik literal, lalu non-titik, lalu satu atau lebih digit, lalu satu titik, lalucss
ataujs
, kemudian akhir nama file. Tidak cocok dengan input sampel Anda: regex101.com/r/RPGC62/1Untuk ASP.NET 4.5 dan lebih tinggi Anda dapat menggunakan bundling skrip .
Ada manfaat lain untuk bundling termasuk peningkatan kinerja pada pemuatan halaman pertama kali dengan minifikasi.
sumber
Ini adalah solusi JavaScript murni
Di atas akan terlihat kapan terakhir kali pengguna mengunjungi situs Anda. Jika kunjungan terakhir adalah sebelum Anda merilis kode baru, itu digunakan
location.reload(true)
untuk memaksa penyegaran halaman dari server.Saya biasanya memiliki ini sebagai skrip pertama dalam
<head>
sehingga dievaluasi sebelum konten lainnya dimuat. Jika perlu memuat ulang, itu hampir tidak terlihat oleh pengguna.Saya menggunakan penyimpanan lokal untuk menyimpan stempel waktu kunjungan terakhir di browser, tetapi Anda dapat menambahkan cookie ke dalam campuran jika Anda ingin mendukung versi IE yang lebih lama.
sumber
Pos yang menarik. Setelah membaca semua jawaban di sini dikombinasikan dengan fakta bahwa saya tidak pernah memiliki masalah dengan string permintaan "palsu" (yang saya tidak yakin mengapa semua orang begitu enggan untuk menggunakan ini) Saya kira solusinya (yang menghilangkan kebutuhan akan aturan penulisan apache apache seperti dalam jawaban yang diterima) adalah untuk menghitung HASH singkat dari isi file CSS (bukan datetime file) sebagai querystring palsu.
Ini akan menghasilkan sebagai berikut:
Tentu saja solusi datetime juga menyelesaikan pekerjaan dalam hal mengedit file CSS tapi saya pikir ini adalah tentang konten file css dan bukan tentang file datetime, jadi mengapa dicampur ini?
sumber
Untuk pengembangan saya, saya menemukan bahwa chrome memiliki solusi hebat.
https://developer.chrome.com/devtools/docs/tips-and-tricks#hard-reload
Dengan alat pengembang terbuka, cukup klik lama tombol refresh dan lepaskan begitu Anda mengarahkan kursor ke "Empty Cache and Hard Reload".
Ini adalah teman terbaik saya, dan merupakan cara yang sangat ringan untuk mendapatkan apa yang Anda inginkan!
sumber
Terima kasih di Kip untuk solusi sempurnanya!
Saya memperluasnya untuk menggunakannya sebagai Zend_view_Helper. Karena klien saya menjalankan halamannya pada virtual host, saya juga memperluasnya untuk itu.
Semoga ini bisa membantu orang lain juga.
Ceria dan terima kasih.
sumber
Belum menemukan pendekatan DOM sisi klien membuat elemen node script (atau css) secara dinamis:
sumber
google chrome memiliki Hard Reload serta opsi Empty Cache dan Hard Reload. Anda dapat mengklik dan menahan tombol reload (Dalam Mode Inspeksi) untuk memilih satu.
sumber
ant menu
>More Tools
>Developer Tools
, aliasright click
>Inspect Element
. Ada juga pengaturan dimakamkan di suatu tempat di alat dev (saya lupa lokasi) untuk memuat ulang keras pada setiap memuat ulang.Anda dapat memaksa "caching sesi-lebar" jika Anda menambahkan id sesi sebagai parameter spureous dari file js / css:
Jika Anda menginginkan cache versi lebar, Anda bisa menambahkan beberapa kode untuk mencetak tanggal file atau yang serupa. Jika Anda menggunakan Java, Anda dapat menggunakan tag-kustom untuk membuat tautan dengan cara yang elegan.
sumber
Katakanlah Anda memiliki file di:
Anda dapat menambahkan parameter kueri dengan informasi versi ke URI, misalnya:
atau Anda dapat menambahkan informasi versi, misalnya:
IMHO metode kedua lebih baik untuk file CSS karena mereka dapat merujuk ke gambar menggunakan URL relatif yang berarti bahwa jika Anda menentukan
background-image
seperti:URL-nya secara efektif adalah:
Ini berarti bahwa jika Anda memperbarui nomor versi yang digunakan server akan memperlakukan ini sebagai sumber daya baru dan tidak menggunakan versi cache. Jika Anda mendasarkan nomor versi Anda pada Subversion / CVS / etc. revisi ini berarti bahwa perubahan pada gambar yang dirujuk dalam file CSS akan diperhatikan. Itu tidak dijamin dengan skema pertama, yaitu URL
images/happy.gif
relatif/styles/screen.css?v=1235
adalah/styles/images/happy.gif
yang tidak mengandung informasi versi apa pun.Saya telah menerapkan solusi caching menggunakan teknik ini dengan servlets Java dan hanya menangani permintaan
/v/*
dengan servlet yang mendelegasikan ke sumber daya yang mendasarinya (yaitu/styles/screen.css
). Dalam modus pembangunan Aku menetapkan caching header yang memberitahu klien untuk selalu memeriksa kesegaran sumber daya dengan server (ini biasanya menghasilkan 304 jika Anda mendelegasikan kepada TomcatDefaultServlet
dan.css
,.js
, dll berkas tidak berubah) saat dalam mode penyebaran Saya menetapkan tajuk yang bertuliskan "cache selamanya".sumber
<?php header( 'Location: folder1/login.phtml' ); ?>
.Anda bisa menambahkan beberapa nomor acak dengan url CSS / JS seperti
sumber
Untuk ASP.NET saya kira solusi berikutnya dengan opsi lanjutan (mode debug / rilis, versi):
File Js atau Css disertakan dengan cara seperti ini:
Global.JsPostfix dan Global.CssPostfix dihitung dengan cara berikut di Global.asax:
sumber
Saya baru-baru ini menyelesaikan ini dengan menggunakan Python. Di sini kodenya (harus mudah diadopsi ke bahasa lain):
Kode ini pada dasarnya menambahkan stempel waktu file sebagai parameter kueri ke URL. Panggilan fungsi berikut
akan menghasilkan
Keuntungannya tentu saja adalah Anda tidak perlu mengubah html lagi, menyentuh file CSS akan secara otomatis memicu pembatalan cache. Bekerja sangat baik dan overhead tidak terlihat.
sumber
Jika Anda menggunakan git + PHP, Anda dapat memuat ulang skrip dari cache setiap kali ada perubahan dalam repo git, menggunakan kode berikut:
sumber
Jika Anda seorang pengembang yang ingin menghindari caching, tab jaringan chrome memiliki opsi cache yang dinonaktifkan. Kalau tidak, Anda bisa melakukannya tanpa kerangka kerja rendering server menggunakan dua tag skrip.
sumber
Pertanyaan ini sudah sangat tua, dan muncul hal pertama ketika ada orang yang googles masalah ini. Ini bukan jawaban untuk pertanyaan seperti yang diinginkan op, melainkan jawaban untuk devs dengan masalah ini saat mengembangkan dan menguji. Dan saya tidak dapat memposting pertanyaan baru tentang topik ini karena akan ditandai sebagai duplikat.
Seperti banyak orang lain, saya hanya ingin menghapus caching sebentar.
"keep caching consistent with the file"
.. terlalu banyak kerumitan ..Secara umum, saya tidak keberatan memuat lebih banyak - bahkan memuat lagi file yang tidak berubah - pada sebagian besar proyek - praktis tidak relevan. Saat mengembangkan aplikasi - kami sebagian besar memuat dari disk, di
localhost:port
- jadiincrease in network traffic
masalah ini bukan masalah pemecahan masalah .Sebagian besar proyek kecil hanya bermain-main - mereka tidak pernah berakhir dalam produksi. jadi bagi mereka Anda tidak perlu lagi ..
Dengan demikian jika Anda menggunakan Alat Dev Chrome , Anda dapat mengikuti pendekatan caching penonaktifan ini seperti pada gambar di bawah ini:
Dan jika Anda memiliki masalah caching firefox :
Lakukan ini hanya dalam pengembangan, Anda juga memerlukan mekanisme untuk memaksa memuat ulang untuk produksi, karena pengguna Anda akan menggunakan modul cache lama yang tidak valid jika Anda sering memperbarui aplikasi dan Anda tidak menyediakan mekanisme sinkronisasi cache khusus seperti yang dijelaskan dalam jawaban. atas.
Ya, info ini sudah ada di jawaban sebelumnya tetapi saya masih perlu melakukan pencarian google untuk menemukannya.
Semoga jawaban ini sangat jelas dan sekarang Anda tidak perlu.
sumber
Tampaknya semua jawaban di sini menyarankan semacam versi dalam skema penamaan, yang memiliki kelemahan.
Peramban harus mengetahui dengan baik apa yang harus di-cache dan apa yang tidak di-cache dengan membaca respons webservers, khususnya header http - untuk berapa lama sumber daya ini valid? Apakah sumber daya ini diperbarui sejak terakhir kali saya mengambilnya? dan sebagainya.
Jika semuanya dikonfigurasi 'dengan benar', hanya memperbarui file aplikasi Anda harus (pada titik tertentu) menyegarkan cache browser. Misalnya Anda dapat mengkonfigurasi server web Anda untuk memberi tahu browser agar tidak pernah menembolok file (yang merupakan ide buruk).
Penjelasan yang lebih mendalam tentang cara kerjanya ada di sini https://www.mnot.net/cache_docs/#WORK
sumber
Cukup tambahkan kode ini, tempat Anda ingin melakukan reload keras (paksa browser untuk memuat ulang file CSS / JS yang di-cache) Lakukan ini di dalam .load agar tidak menyegarkan seperti loop
sumber
Cukup gunakan kode sisi server untuk menambahkan tanggal file ... dengan cara itu AKAN di-cache dan hanya dimuat ulang ketika file berubah
Di ASP.NET
Ini dapat disederhanakan untuk:
Dengan menambahkan metode ekstensi ke proyek Anda untuk memperluas Halaman:
sumber
Saya sarankan menerapkan proses berikut:
versi file css / js Anda setiap kali Anda menyebarkan, sesuatu seperti: screen.1233.css (nomor tersebut dapat menjadi revisi SVN Anda jika Anda menggunakan sistem versi)
minify mereka untuk mengoptimalkan waktu pemuatan
sumber