Saya mengakses tautan di situs saya yang akan memberikan gambar baru setiap kali diakses.
Masalah yang saya hadapi adalah bahwa jika saya mencoba memuat gambar di latar belakang dan kemudian memperbarui gambar di halaman, gambar tidak berubah - meskipun diperbarui ketika saya memuat ulang halaman.
var newImage = new Image();
newImage.src = "http://localhost/image.jpg";
function updateImage()
{
if(newImage.complete) {
document.getElementById("theText").src = newImage.src;
newImage = new Image();
number++;
newImage.src = "http://localhost/image/id/image.jpg?time=" + new Date();
}
setTimeout(updateImage, 1000);
}
Header sebagaimana FireFox melihatnya:
HTTP/1.x 200 OK
Cache-Control: no-cache, must-revalidate
Pragma: no-cache
Transfer-Encoding: chunked
Content-Type: image/jpeg
Expires: Fri, 30 Oct 1998 14:19:41 GMT
Server: Microsoft-HTTPAPI/1.0
Date: Thu, 02 Jul 2009 23:06:04 GMT
Saya perlu memaksakan penyegaran hanya pada gambar itu di halaman. Ada ide?
javascript
image
url
refresh
QueueHammer
sumber
sumber
Jawaban:
Coba tambahkan pembuka obrolan di akhir url:
Ini akan menambahkan cap waktu saat ini secara otomatis ketika Anda membuat gambar, dan itu akan membuat browser mencari lagi untuk gambar alih-alih mengambil yang ada di cache.
sumber
'image.jpg?' + (+new Date())
Date.now()
untuk iniMath.random()
Saya telah melihat banyak variasi dalam jawaban untuk bagaimana melakukan ini, jadi saya pikir saya akan meringkasnya di sini (ditambah menambahkan metode ke-4 dari penemuan saya sendiri):
(1) Tambahkan parameter kueri penghilang cache yang unik ke URL, seperti:
Kelebihan: 100% andal, cepat & mudah dipahami dan diimplementasikan.
Cons: Bypass caching sama sekali, berarti penundaan yang tidak perlu dan penggunaan bandwidth setiap kali gambar tidak berubah di antara tampilan. Akan berpotensi mengisi cache browser (dan cache perantara) dengan banyak, banyak salinan gambar yang persis sama! Juga, membutuhkan modifikasi URL gambar.
Kapan harus digunakan: Gunakan saat gambar terus berubah, seperti untuk umpan webcam langsung. Jika Anda menggunakan metode ini, pastikan untuk menyajikan gambar itu sendiri dengan
Cache-control: no-cache
header HTTP !!! (Seringkali ini dapat diatur menggunakan file .htaccess). Kalau tidak, Anda akan secara progresif mengisi cache dengan versi gambar yang lama!(2) Tambahkan parameter kueri ke URL yang hanya berubah ketika file melakukannya, misalnya:
(Itu kode sisi server PHP, tetapi poin penting di sini adalah hanya querystring ? M = [file last-modified] ditambahkan ke nama file).
Kelebihan: 100% andal, cepat & mudah dipahami dan diimplementasikan, dan menjaga keunggulan caching dengan sempurna.
Cons: Membutuhkan memodifikasi URL gambar. Juga, sedikit lebih banyak pekerjaan untuk server - itu harus mendapatkan akses ke waktu file-terakhir diubah. Juga, memerlukan informasi sisi server, jadi tidak cocok untuk solusi murni sisi-klien untuk memeriksa gambar yang di-refresh.
Kapan menggunakan: Ketika Anda ingin menyimpan gambar, tetapi mungkin perlu memperbaruinya di server dari waktu ke waktu tanpa mengubah nama file itu sendiri. DAN ketika Anda dapat dengan mudah memastikan bahwa querystring yang benar ditambahkan ke setiap instance gambar dalam HTML Anda.
(3) Sajikan gambar Anda dengan tajuk
Cache-control: max-age=0, must-revalidate
, dan tambahkan memcache -busting identifier fragmen unik ke URL, seperti:Idenya di sini adalah bahwa header-kontrol cache menempatkan gambar dalam cache browser, tetapi segera menandai mereka basi, sehingga setiap kali mereka ditampilkan kembali browser harus memeriksa dengan server untuk melihat apakah mereka telah berubah. Ini memastikan bahwa cache HTTP browser selalu mengembalikan salinan gambar terbaru. Namun, browser akan sering menggunakan kembali salinan gambar dalam memori jika mereka memilikinya, dan bahkan tidak memeriksa cache HTTP mereka dalam kasus itu. Untuk mencegah hal ini, pengidentifikasi fragmen digunakan: Perbandingan di dalam memori gambar
src
termasuk pengidentifikasi fragmen, tapi itu dilucuti sebelum meminta cache HTTP. (Jadi, misalnya,image.jpg#A
danimage.jpg#B
mungkin keduanya ditampilkan dariimage.jpg
entri di cache HTTP browser, tetapiimage.jpg#B
tidak akan pernah ditampilkan menggunakan data gambar yang disimpan dalam memori sejak kapanimage.jpg#A
terakhir ditampilkan).Kelebihan: Menggunakan mekanisme cache HTTP yang benar, dan menggunakan gambar cache jika tidak diubah. Bekerja untuk server yang tersedak querystring ditambahkan ke URL gambar statis (karena server tidak pernah melihat pengidentifikasi fragmen - mereka hanya untuk penggunaan browser sendiri).
Kekurangan: Bergantung pada perilaku browser yang agak meragukan (atau paling tidak didokumentasikan dengan buruk), sehubungan dengan gambar dengan pengidentifikasi fragmen di URL mereka (Namun, saya telah menguji ini dengan sukses di FF27, Chrome33, dan IE11). Apakah masih mengirim permintaan validasi ulang ke server untuk setiap tampilan gambar, yang mungkin berlebihan jika gambar hanya jarang berubah dan / atau latensi adalah masalah besar (karena Anda perlu menunggu respon validasi ulang bahkan ketika gambar yang di-cache masih bagus) . Membutuhkan modifikasi URL gambar.
Kapan harus digunakan: Gunakan ketika gambar mungkin sering berubah, atau perlu disegarkan sesekali oleh klien tanpa keterlibatan skrip sisi server, tetapi di mana Anda masih menginginkan keuntungan dari caching. Misalnya, polling webcam langsung yang memperbarui gambar secara tidak teratur setiap beberapa menit. Atau, gunakan alih-alih (1) atau (2) jika server Anda tidak mengizinkan querystrings pada URL gambar statis.
(4) Segarkan secara paksa gambar tertentu menggunakan Javascript, dengan terlebih dahulu memuatnya ke tersembunyi
<iframe>
dan kemudian memanggillocation.reload(true)
iframecontentWindow
.Langkah-langkahnya adalah:
Muat gambar untuk disegarkan ke dalam iframe tersembunyi. Ini hanya langkah penyiapan - bisa dilakukan jauh-jauh hari sebelum penyegaran aktual, jika diinginkan. Bahkan tidak masalah jika gambar gagal dimuat pada tahap ini!
Setelah selesai, kosongkan semua salinan gambar itu di laman Anda atau di mana pun di simpul DOM (bahkan di luar laman yang disimpan dalam variabel javascript). Ini diperlukan karena browser dapat menampilkan gambar dari salinan dalam-basi basi (IE11 terutama melakukan ini): Anda perlu memastikan semua salinan dalam-memori dihapus, sebelum menyegarkan cache HTTP. Jika kode javascript lain berjalan secara tidak serempak, Anda mungkin juga perlu mencegah kode itu membuat salinan baru dari gambar yang akan di-refresh sementara itu.
Panggil
iframe.contentWindow.location.reload(true)
. Thetrue
pasukan bypass cache reload langsung dari server dan Timpa salinan cache yang ada.Setelah selesai memuat ulang , kembalikan gambar yang kosong. Mereka sekarang harus menampilkan versi baru dari server!
Untuk gambar dengan domain yang sama, Anda dapat memuat gambar ke iframe secara langsung. Untuk gambar lintas-domain, Anda harus memuat halaman HTML dari domain Anda yang berisi gambar dalam
<img>
tag, jika tidak, Anda akan mendapatkan kesalahan "Akses Ditolak" ketika mencoba meneleponiframe.contentWindow.reload(...)
.Pro: Berfungsi persis seperti fungsi image.reload () yang Anda inginkan dimiliki DOM! Mengizinkan gambar di-cache secara normal (bahkan dengan tanggal kedaluwarsa di masa mendatang jika Anda menginginkannya, sehingga menghindari revalidasi yang sering dilakukan). Memungkinkan Anda menyegarkan gambar tertentu tanpa mengubah URL untuk gambar itu di halaman saat ini, atau di halaman lain, hanya menggunakan kode sisi klien.
Cons: Bergantung pada Javascript. Tidak 100% dijamin berfungsi dengan baik di setiap browser (saya sudah mencoba ini dengan sukses di FF27, Chrome33, dan IE11). Sangat rumit dibandingkan metode lainnya.
Kapan harus digunakan: Ketika Anda memiliki koleksi gambar yang pada dasarnya statis yang ingin Anda cache, tetapi Anda masih harus dapat memperbaruinya sesekali dan mendapatkan umpan balik visual segera bahwa pembaruan itu terjadi. (Terutama ketika me-refresh seluruh halaman browser tidak akan berfungsi, seperti pada beberapa aplikasi web yang dibangun di AJAX misalnya). Dan ketika metode (1) - (3) tidak layak karena (untuk alasan apa pun) Anda tidak dapat mengubah semua URL yang mungkin berpotensi menampilkan gambar yang harus Anda perbarui. (Perhatikan bahwa menggunakan 3 metode itu gambar akan di-refresh, tetapi jika halaman lain kemudian mencoba untuk menampilkan gambar itu tanpa querystring atau pengidentifikasi fragmen yang tepat, itu mungkin akan menunjukkan versi yang lebih lama).
Rincian penerapan ini dalam peri yang kuat dan fleksibel diberikan di bawah ini:
Anggap situs web Anda mengandung 1x1 piksel kosong .gif di jalur URL
/img/1x1blank.gif
, dan juga memiliki skrip PHP satu baris berikut (hanya diperlukan untuk menerapkan penyegaran paksa ke gambar lintas-domain , dan dapat ditulis ulang dalam bahasa skrip sisi server apa pun , tentu saja) di jalur URL/echoimg.php
:Kemudian, inilah implementasi realistis tentang bagaimana Anda dapat melakukan semua ini dalam Javascript. Ini terlihat agak rumit, tetapi ada banyak komentar, dan fungsi yang penting adalah forceImgReload () - dua yang pertama hanya gambar kosong dan tidak kosong, dan harus dirancang untuk bekerja secara efisien dengan HTML Anda sendiri, jadi beri kode sebagai terbaik untuk Anda; banyak komplikasi di dalamnya mungkin tidak perlu untuk situs web Anda:
Kemudian, untuk memaksa penyegaran gambar yang terletak di domain yang sama dengan halaman Anda, Anda bisa melakukan:
Untuk menyegarkan gambar dari tempat lain (lintas-domain):
Aplikasi yang lebih maju mungkin memuat ulang gambar setelah mengunggah versi baru ke server Anda, menyiapkan tahap awal proses memuat ulang secara bersamaan dengan mengunggah, untuk meminimalkan keterlambatan pemuatan yang terlihat oleh pengguna. Jika Anda melakukan unggahan melalui AJAX, dan server mengembalikan array JSON yang sangat sederhana [sukses, lebar, tinggi] maka kode Anda mungkin terlihat seperti ini:
Catatan terakhir: Meskipun topik ini membahas tentang gambar, topik ini juga berpotensi berlaku untuk jenis file atau sumber lainnya. Misalnya, mencegah penggunaan skrip basi atau file css, atau bahkan mungkin menyegarkan dokumen PDF yang diperbarui (menggunakan (4) hanya jika diatur untuk membuka di-browser). Metode (4) mungkin memerlukan beberapa perubahan pada javascript di atas, dalam kasus ini.
sumber
image.jpg#123
menjadiimage.jpg#124
(atau apa pun, asalkan bit setelah perubahan '#'). Bisakah Anda mengklarifikasi apa yang Anda reload, dan mengapa?contentWindow
melalui javascript untuk melakukanreload(true)
panggilan yang merupakan bagian penting dari metode ... jadi tidak, metode (4) ) tidak akan berfungsi untuk konten lintas domain. Terlihat dengan baik; Saya akan memperbarui "Kontra" untuk memasukkan itu.Sebagai alternatif untuk ...
...tampaknya...
... cukup untuk mengelabui cache browser tanpa melewati cache upstream apa pun, dengan asumsi Anda mengembalikan
Cache-Control
header yang benar . Meskipun Anda dapat menggunakan ...... Anda kehilangan manfaat dari header
If-Modified-Since
atauIf-None-Match
, jadi sesuatu seperti ...... harus mencegah browser mengunduh ulang seluruh gambar jika belum benar-benar berubah. Diuji dan bekerja pada IE, Firefox, dan Chrome. Mengganggu gagal di Safari kecuali jika Anda menggunakan ...
... meskipun ini masih lebih baik daripada mengisi cache upstream dengan ratusan gambar yang identik, terutama ketika mereka berjalan di server Anda sendiri. ;-)
Pembaruan (2014-09-28): Saat ini sepertinya
Cache-Control: no-store
diperlukan juga untuk Chrome.sumber
src
atribut lengkap , jadi menambahkan pengenal fragmen yang unik memastikan bahwa gambar tidak hanya ditarik dari memori. Tetapi pengidentifikasi fragmen tidak dikirim sebagai bagian dari permintaan HTTP, sehingga cache HTTP biasa akan digunakan seperti biasa. Itu sebabnya teknik ini berhasil.Cache-Control: max-age=0, must-revalidate
baik untuk saya?newImage.src = "http://localhost/image.jpg#" + i++;
Setelah membuat gambar baru, apakah Anda menghapus gambar lama dari DOM dan menggantinya dengan yang baru?
Anda bisa mengambil gambar baru setiap panggilan updateImage, tetapi tidak menambahkannya ke halaman.
Ada sejumlah cara untuk melakukannya. Sesuatu seperti ini akan berhasil.
Setelah berhasil, jika masih ada masalah, mungkin masalah caching seperti yang dibicarakan jawaban lain.
sumber
Salah satu jawabannya adalah menambahkan beberapa parameter permintaan kueri seperti yang disarankan.
Jawaban yang lebih baik adalah memancarkan beberapa opsi tambahan di header HTTP Anda.
Dengan memberikan tanggal di masa lalu, itu tidak akan di-cache oleh browser.
Cache-Control
ditambahkan dalam HTTP / 1.1 dan tag yang harus divalidasi ulang menunjukkan bahwa proksi tidak boleh menampilkan gambar lama bahkan dalam keadaan meringankan, dan yangPragma: no-cache
tidak benar-benar diperlukan untuk browser / cache modern saat ini tetapi dapat membantu dengan beberapa implementasi lama yang rusak.sumber
Saya memiliki persyaratan: 1) tidak dapat menambahkan apapun
?var=xx
ke gambar 2) itu harus bekerja lintas domainSaya sangat suka opsi # 4 dalam jawaban ini dengan satu tetapi:
Cara cepat dan kotor saya adalah:
iframe.contentWindow.location.reload(true);
Ini dia
Ya, saya tahu, setTimeout ... Anda harus mengubahnya untuk melakukan onload-events yang tepat.
sumber
Kemudian di bawah ini di beberapa javascript
Jadi yang dilakukan adalah, ketika gambar dimuat, menjadwalkannya untuk dimuat ulang dalam 1 detik. Saya menggunakan ini pada halaman dengan kamera keamanan rumah dari berbagai jenis.
sumber
Apa yang akhirnya saya lakukan adalah meminta server memetakan permintaan gambar pada direktori itu ke sumber yang saya coba perbarui. Saya kemudian memiliki timer saya menambahkan nomor pada akhir nama sehingga DOM akan melihatnya sebagai gambar baru dan memuatnya.
Misalnya
akan meminta kode pembuatan gambar yang sama tetapi akan terlihat seperti gambar berbeda untuk browser.
sumber
sumber
../showImage.phpFri May 01 2015 17:34:18 GMT+0200 (Mitteleuropäische Sommerzeit)
adalah nama file yang valid ... Setidaknya ini yang mencoba memuat ...path='../showImage.php';
kepath='../showImage.php?';
atur src sendiri sebagai src-nya.
sumber
Coba gunakan querystring yang tidak berguna untuk menjadikannya url unik:
sumber
Sangat didasarkan pada Doin ini # 4 kode, contoh berikut ini menyederhanakan kode sedikit besar memanfaatkan
document.write
bukannyasrc
diiframe
untuk mendukung CORS. Juga hanya berfokus pada penghilang cache browser, tidak memuat ulang setiap gambar pada halaman.Di bawah ini ditulis
typescript
dan menggunakan perpustakaan janjiangular
$ q , hanya fyi, tetapi harus cukup mudah untuk port ke vanilla javascript. Metode dimaksudkan untuk hidup di dalam kelas naskah.Mengembalikan janji yang akan diselesaikan ketika iframe telah selesai memuat ulang. Tidak banyak diuji, tetapi bekerja dengan baik untuk kita.
sumber
+ encodeURI(src) +
untuk benar melarikan dirisrc
diiframe
.Kode berikut berguna untuk menyegarkan gambar ketika tombol diklik.
sumber
Saya memecahkan masalah ini dengan mengirim data kembali melalui servlet.
Kemudian dari halaman Anda hanya memberikan servlet dengan beberapa params untuk mengambil file gambar yang benar.
sumber
Inilah solusi saya. Ini sangat sederhana. Penjadwalan bingkai bisa lebih baik.
sumber
Tidak perlu
new Date().getTime()
shenanigans. Anda dapat mengelabui browser dengan memiliki gambar dummy yang tidak terlihat dan menggunakan jQuery .load (), lalu membuat gambar baru setiap kali:sumber
Solusi sederhana: tambahkan tajuk ini ke respons:
Mengapa ini bekerja dengan jelas dijelaskan di halaman otoritatif ini: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
Itu juga menjelaskan mengapa
no-cache
tidak bekerja.Jawaban lain tidak berfungsi karena:
Caching.delete
adalah tentang cache baru yang dapat Anda buat untuk pekerjaan offline, lihat: https://web.dev/cache-api-quick-guide/Fragmen yang menggunakan # di URL tidak berfungsi karena # memberi tahu browser untuk tidak mengirim permintaan ke server.
Cache-buster dengan bagian acak yang ditambahkan ke url berfungsi, tetapi juga akan mengisi cache browser. Di aplikasi saya, saya ingin mengunduh gambar 5 MB setiap beberapa detik dari web cam. Ini akan memakan waktu hanya satu jam atau kurang untuk sepenuhnya membekukan komputer Anda. Saya masih tidak tahu mengapa cache browser tidak terbatas pada maks yang masuk akal, tetapi ini jelas merupakan kerugian.
sumber
Saya meningkatkan skrip dari AlexMA untuk menunjukkan webcam saya di halaman web yang secara berkala mengunggah gambar baru dengan nama yang sama. Saya mengalami masalah yang terkadang gambarnya berkedip-kedip karena gambar yang rusak atau tidak lengkapnya gambar yang dimuat. Untuk mencegah kerlipan, saya memeriksa ketinggian alami gambar karena ukuran gambar webcam saya tidak berubah. Hanya jika tinggi gambar yang dimuat sesuai dengan tinggi gambar asli, gambar penuh akan ditampilkan di halaman.
sumber
Saya menggunakan konsep di bawah ini pertama-tama mengikat gambar dengan url (buffer) palsu dan selanjutnya mengikatnya dengan url yang valid.
Dengan cara ini, saya memaksa browser untuk menyegarkan dengan url yang valid.
sumber