มีวิธีที่ฉันสามารถใส่รหัสบางอย่างในหน้าของฉันดังนั้นเมื่อมีคนเข้าชมเว็บไซต์มันล้างแคชเบราว์เซอร์เพื่อให้พวกเขาสามารถดูการเปลี่ยนแปลงได้หรือไม่
ภาษาที่ใช้: ASP.NET, VB.NET และแน่นอน HTML, CSS และ jQuery
มีวิธีที่ฉันสามารถใส่รหัสบางอย่างในหน้าของฉันดังนั้นเมื่อมีคนเข้าชมเว็บไซต์มันล้างแคชเบราว์เซอร์เพื่อให้พวกเขาสามารถดูการเปลี่ยนแปลงได้หรือไม่
ภาษาที่ใช้: ASP.NET, VB.NET และแน่นอน HTML, CSS และ jQuery
คำตอบ:
หากนี่เป็นเรื่องเกี่ยวกับ.css
และ.js
การเปลี่ยนแปลงวิธีหนึ่งคือการ "หยุดการใช้แคช" คือการต่อท้ายชื่อ "" ต่อท้าย_versionNo
ชื่อไฟล์สำหรับแต่ละรุ่น ตัวอย่างเช่น:
script_1.0.css // This is the URL for release 1.0
script_1.1.css // This is the URL for release 1.1
script_1.2.css // etc.
หรือทำอย่างอื่นหลังจากชื่อไฟล์:
script.css?v=1.0 // This is the URL for release 1.0
script.css?v=1.1 // This is the URL for release 1.1
script.css?v=1.2 // etc.
คุณสามารถตรวจสอบลิงค์นี้เพื่อดูว่ามันทำงานอย่างไร
script.js?v=1.2
แต่ผนวกหมายเลขรุ่นเป็นพารามิเตอร์สตริงการสืบค้นเช่น (หรือหากคุณไม่ได้ติดตามเวอร์ชั่นให้ใช้ไฟล์ที่แก้ไขครั้งล่าสุดซึ่งทำได้ง่ายกว่า) ไม่แน่ใจว่าเป็นสิ่งที่ผู้วิจารณ์คนก่อนหน้าหมายถึง!
<link />
แท็กแบบไดนามิกและฉีดเวอร์ชันของแอปพลิเคชันเป็นพารามิเตอร์สตริงแบบสอบถาม อีกวิธีหนึ่ง CMSes บางอย่างจะมี "รุ่นทรัพยากรของลูกค้า" เป็นการตั้งค่าแบบกว้างของ CMS ที่ต่อท้าย - ผู้ดูแลระบบของไซต์สามารถเพิ่มเวอร์ชัน nr ด้วยตนเองและการปรับปรุง CMS สามารถอัปเดตได้โดยอัตโนมัติ บรรทัดล่าง: คุณต้องแสดง URL ของไฟล์แบบไดนามิก
ดูที่การควบคุมแคชและแท็ก META ที่หมดอายุ
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
<META HTTP-EQUIV="EXPIRES" CONTENT="Mon, 22 Jul 2002 11:12:01 GMT">
แนวทางปฏิบัติทั่วไปอีกประการหนึ่งคือการผนวกสตริงที่เปลี่ยนแปลงตลอดเวลาไปยังจุดสิ้นสุดของไฟล์ที่ร้องขอ ตัวอย่างเช่น
<script type="text/javascript" src="main.js?v=12392823"></script>
นี่เป็นคำถามเก่า แต่ฉันคิดว่ามันต้องการคำตอบที่ทันสมัยมากขึ้นเพราะตอนนี้มีวิธีที่จะควบคุมการแคชเว็บไซต์ได้มากขึ้น
ในแอปพลิเคชันเว็บออฟไลน์ (ซึ่งจริงๆแล้วเป็นเว็บไซต์ HTML5 ใด ๆ ) applicationCache.swapCache()
สามารถใช้เพื่ออัปเดตเวอร์ชันที่แคชของเว็บไซต์ของคุณโดยไม่จำเป็นต้องโหลดหน้าซ้ำด้วยตนเอง
นี่คือตัวอย่างรหัสจากคู่มือผู้เริ่มต้นใช้งานแอปพลิเคชันแคชบน HTML5 Rocks ซึ่งอธิบายวิธีอัปเดตผู้ใช้เป็นเว็บไซต์รุ่นใหม่ล่าสุด:
// Check if a new cache is available on page load.
window.addEventListener('load', function(e) {
window.applicationCache.addEventListener('updateready', function(e) {
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
// Browser downloaded a new app cache.
// Swap it in and reload the page to get the new hotness.
window.applicationCache.swapCache();
if (confirm('A new version of this site is available. Load it?')) {
window.location.reload();
}
} else {
// Manifest didn't changed. Nothing new to server.
}
}, false);
}, false);
ดูเพิ่มเติมการใช้แอปพลิเคชันแคชบน Mozilla Developer Network สำหรับข้อมูลเพิ่มเติม
สิ่งต่าง ๆ เปลี่ยนแปลงอย่างรวดเร็วบนเว็บ คำถามนี้ถูกถามในปี 2009 และในปี 2012 ฉันโพสต์การอัปเดตเกี่ยวกับวิธีการใหม่ในการจัดการปัญหาที่อธิบายไว้ในคำถาม อีก 4 ปีผ่านไปและตอนนี้ดูเหมือนว่าจะเลิกใช้แล้ว ขอบคุณcgaldiolo ที่ชี้ให้เห็นในความคิดเห็น
ปัจจุบัน ณ เดือนกรกฎาคม 2559 มาตรฐาน HTML มาตรา 7.9 แอปพลิเคชันเว็บออฟไลน์มีคำเตือนการเลิกใช้
คุณลักษณะนี้อยู่ในขั้นตอนการลบออกจากแพลตฟอร์มเว็บ (นี่เป็นกระบวนการที่ใช้เวลานานหลายปี) การใช้คุณลักษณะแอปพลิเคชันเว็บออฟไลน์ใด ๆ ในเวลานี้ก็ไม่ได้รับการสนับสนุนอย่างมาก ใช้พนักงานบริการแทน
ดังนั้นการใช้แอปพลิเคชันแคชบน Mozilla Developer Network ที่ฉันอ้างอิงในปี 2012:
เลิกใช้
คุณสมบัตินี้ถูกลบออกจากเว็บมาตรฐาน แม้ว่าเบราว์เซอร์บางตัวอาจยังคงสนับสนุนอยู่ แต่กำลังอยู่ระหว่างการทำตก ห้ามใช้ในโครงการเก่าหรือใหม่ หน้าหรือเว็บแอปที่ใช้งานอาจหยุดพักเมื่อใดก็ได้
ดูเพิ่มเติมBug 1204581 - เพิ่มการแจ้งเลิกใช้สำหรับ AppCache ถ้าผู้ปฏิบัติงานบริการสามารถดึงข้อมูลการสกัดกั้นถูกเปิดใช้งาน
ไม่เป็นเช่นนั้น วิธีหนึ่งคือส่งส่วนหัวที่เหมาะสมเมื่อส่งเนื้อหาเพื่อบังคับให้เบราว์เซอร์โหลดซ้ำ:
ตรวจสอบให้แน่ใจว่าหน้าเว็บไม่ได้ถูกแคชในทุกเบราว์เซอร์
หากการค้นหาของคุณ"cache header"
หรือสิ่งที่คล้ายกันใน SO คุณจะพบตัวอย่างเฉพาะของ ASP.NET
วิธีอื่นที่สะอาดน้อยกว่า แต่บางครั้งก็เฉพาะถ้าคุณไม่สามารถควบคุมส่วนหัวทางฝั่งเซิร์ฟเวอร์ได้คือการเพิ่มพารามิเตอร์ GET แบบสุ่มเข้ากับทรัพยากรที่ถูกเรียกใช้:
myimage.gif?random=1923849839
สำหรับทรัพยากรคงที่แคชขวาจะใช้พารามิเตอร์แบบสอบถามที่มีค่าของการปรับใช้หรือรุ่นของไฟล์แต่ละ นี่จะมีผลกระทบของการล้างแคชหลังจากการปรับใช้แต่ละครั้ง
/Content/css/Site.css?version={FileVersionNumber}
นี่คือตัวอย่าง ASP.NET MVC
<link href="@Url.Content("~/Content/Css/Reset.css")?version=@this.GetType().Assembly.GetName().Version" rel="stylesheet" type="text/css" />
อย่าลืมอัปเดตเวอร์ชั่นประกอบ
?version=@ViewContext.Controller.GetType().Assembly.GetName().Version
ฉันมีปัญหาที่คล้ายกันและนี่คือวิธีที่ฉันจะแก้ไข:
ในindex.html
ไฟล์ที่ฉันได้เพิ่มรายการ:
<html manifest="cache.manifest">
ใน<head>
ส่วนรวมสคริปต์การปรับปรุงแคช:
<script type="text/javascript" src="update_cache.js"></script>
ใน<body>
ส่วนที่ฉันได้แทรกฟังก์ชั่น onload:
<body onload="checkForUpdate()">
ในcache.manifest
ฉันได้ใส่ไฟล์ทั้งหมดที่ฉันต้องการแคช ตอนนี้มันเป็นสิ่งสำคัญที่ใช้งานได้ในกรณีของฉัน (Apache) เพียงแค่อัปเดตความคิดเห็น "รุ่น" ทุกครั้ง นอกจากนี้ยังเป็นตัวเลือกที่จะตั้งชื่อไฟล์ที่มี "? Ver = 001" หรือบางสิ่งบางอย่างในตอนท้ายของชื่อ แต่ก็ไม่จำเป็นต้องใช้ การเปลี่ยนเพียงแค่# version 1.01
เรียกใช้เหตุการณ์การอัพเดตแคช
CACHE MANIFEST
# version 1.01
style.css
imgs/logo.png
#all other files
สิ่งสำคัญคือต้องรวม 1. , 2 และ 3. เฉพาะใน index.html มิฉะนั้น
GET http://foo.bar/resource.ext net::ERR_FAILED
เกิดขึ้นเนื่องจากไฟล์ "เด็ก" ทุกคนพยายามที่จะแคชหน้าในขณะที่หน้าแคชแล้ว
ในupdate_cache.js
ไฟล์ฉันได้ใส่รหัสนี้:
function checkForUpdate()
{
if (window.applicationCache != undefined && window.applicationCache != null)
{
window.applicationCache.addEventListener('updateready', updateApplication);
}
}
function updateApplication(event)
{
if (window.applicationCache.status != 4) return;
window.applicationCache.removeEventListener('updateready', updateApplication);
window.applicationCache.swapCache();
window.location.reload();
}
ตอนนี้คุณเพียงแค่เปลี่ยนไฟล์และในรายการคุณจะต้องอัปเดตความคิดเห็นรุ่น ตอนนี้ไปที่หน้า index.html จะอัปเดตแคช
ส่วนของการแก้ปัญหาไม่ใช่ของฉัน แต่ฉันได้พบพวกเขาผ่านอินเทอร์เน็ตและรวบรวมเพื่อให้ใช้งานได้
ฉันมีกรณีที่ฉันจะถ่ายรูปลูกค้าออนไลน์และจะต้องอัปเดต div หากภาพถ่ายเปลี่ยนไป เบราว์เซอร์ยังคงแสดงภาพเก่า ดังนั้นฉันจึงใช้แฮ็คในการเรียกตัวแปร GET แบบสุ่มซึ่งจะไม่ซ้ำกันทุกครั้ง นี่คือถ้ามันสามารถช่วยใครก็ได้
<img src="/photos/userid_73.jpg?random=<?php echo rand() ?>" ...
แก้ไขตามที่คนอื่น ๆ ชี้ให้เห็นการแก้ปัญหาต่อไปนี้เป็นวิธีที่มีประสิทธิภาพมากกว่าเนื่องจากจะโหลดภาพเมื่อมีการเปลี่ยนแปลงเท่านั้นซึ่งจะระบุการเปลี่ยนแปลงนี้ตามขนาดไฟล์:
<img src="/photos/userid_73.jpg?modified=<? filemtime("/photos/userid_73.jpg")?>"
มีคำตอบมากมายที่หายไป - นักพัฒนาส่วนใหญ่ทราบดีว่าการปิดแคชไม่มีประสิทธิภาพ อย่างไรก็ตามมีสถานการณ์ทั่วไปมากมายที่ประสิทธิภาพไม่สำคัญและพฤติกรรมแคชเริ่มต้นเสียอย่างรุนแรง
เหล่านี้รวมถึงการทดสอบสคริปต์ที่ซ้ำซ้อน (ใหญ่) และการแก้ไขปัญหาซอฟต์แวร์ของ บริษัท อื่น ไม่มีวิธีการแก้ปัญหาที่ให้ไว้ที่นี่เพียงพอที่จะแก้ไขสถานการณ์ทั่วไปดังกล่าว เว็บเบราว์เซอร์ส่วนใหญ่ใช้วิธีแคชที่ก้าวร้าวมากเกินไปและไม่มีวิธีการที่เหมาะสมในการหลีกเลี่ยงปัญหาเหล่านี้
<meta http-equiv="pragma" content="no-cache" />
โปรดดู/programming/126772/how-to-force-a-web-browser-not-to-cache-images
การอัปเดต URL เป็นสิ่งต่อไปนี้ใช้งานได้สำหรับฉัน:
/custom.js?id=1
ด้วยการเพิ่มหมายเลขเฉพาะหลังจากนั้น?id=
และเพิ่มขึ้นสำหรับการเปลี่ยนแปลงใหม่ผู้ใช้ไม่จำเป็นต้องกดCTRL + F5
เพื่อรีเฟรชแคช อีกวิธีหนึ่งคุณสามารถผนวกแฮชหรือรุ่นสตริงของเวลาปัจจุบันหรือยุคหลังจาก?id=
สิ่งที่ต้องการ ?id=1520606295
นี่คือหน้า MDSN ในการตั้งค่าแคชใน ASP.NET
Response.Cache.SetExpires(DateTime.Now.AddSeconds(60))
Response.Cache.SetCacheability(HttpCacheability.Public)
Response.Cache.SetValidUntilExpires(False)
Response.Cache.VaryByParams("Category") = True
If Response.Cache.VaryByParams("Category") Then
'...
End If
ไม่แน่ใจว่าสิ่งนี้อาจช่วยคุณได้จริงหรือไม่ เมื่อเบราว์เซอร์ร้องขอไฟล์ควรส่งคำขอไปยังเซิร์ฟเวอร์ทุกครั้งเว้นแต่จะมีโหมด "ออฟไลน์" เซิร์ฟเวอร์จะอ่านพารามิเตอร์บางอย่างเช่นวันที่แก้ไขหรือ etags
เซิร์ฟเวอร์จะส่งกลับข้อผิดพลาด 304 สำหรับการไม่แก้ไขและเบราว์เซอร์จะต้องใช้แคช หาก etag ไม่ผ่านการตรวจสอบด้านเซิร์ฟเวอร์หรือวันที่แก้ไขต่ำกว่าวันที่แก้ไขปัจจุบันเซิร์ฟเวอร์ควรส่งคืนเนื้อหาใหม่ด้วยวันที่แก้ไขใหม่หรือ etags หรือทั้งสองอย่าง
หากไม่มีการแคชข้อมูลที่ส่งไปยังเบราว์เซอร์ฉันคิดว่าพฤติกรรมนั้นไม่ได้รับการกำหนดเบราว์เซอร์อาจหรืออาจไม่แคชไฟล์ที่ไม่ได้บอกวิธีที่แคช หากคุณตั้งค่าพารามิเตอร์การแคชในการตอบสนองมันจะแคชไฟล์ของคุณอย่างถูกต้องและเซิร์ฟเวอร์อาจเลือกที่จะส่งคืนข้อผิดพลาด 304 หรือเนื้อหาใหม่
นี่คือวิธีที่ควรทำ การใช้พารามิเตอร์แบบสุ่มหรือหมายเลขรุ่นใน URL เป็นเหมือนแฮ็คมากกว่าทุกสิ่ง
http://www.checkupdown.com/status/E304.html http://en.wikipedia.org/wiki/HTTP_ETag http://www.xpertdeveloper.com/2011/03/last-modified-header-vs- หมดอายุหัว-VS-etag /
หลังจากอ่านแล้วฉันเห็นว่ายังมีวันหมดอายุ หากคุณมีปัญหาอาจเป็นไปได้ว่าคุณมีวันที่หมดอายุ กล่าวอีกนัยหนึ่งเมื่อเบราว์เซอร์จะแคชไฟล์ของคุณเนื่องจากมีวันหมดอายุจึงไม่จำเป็นต้องขออีกครั้งก่อนวันที่ดังกล่าว มันจะไม่ขอไฟล์ไปยังเซิร์ฟเวอร์และจะไม่ได้รับ 304 ที่ไม่ได้แก้ไข มันจะใช้แคชจนกว่าจะถึงวันหมดอายุหรือล้างแคช
นั่นคือการเดาของฉันคุณมีวันหมดอายุบางประเภทและคุณควรใช้ Etags ที่แก้ไขล่าสุดหรือรวมกันทั้งหมดและตรวจสอบให้แน่ใจว่าไม่มีวันหมดอายุ
หากผู้คนมีแนวโน้มที่จะรีเฟรชเป็นจำนวนมากและไฟล์ไม่ได้รับการเปลี่ยนแปลงมากนักก็ควรที่จะกำหนดวันหมดอายุที่ยิ่งใหญ่
2 เซ็นต์ของฉัน!
ฉันใช้โซลูชันง่ายๆนี้ที่เหมาะกับฉัน (ยังไม่ได้อยู่ในสภาพแวดล้อมการผลิต):
function verificarNovaVersio() {
var sVersio = localStorage['gcf_versio'+ location.pathname] || 'v00.0.0000';
$.ajax({
url: "./versio.txt"
, dataType: 'text'
, cache: false
, contentType: false
, processData: false
, type: 'post'
}).done(function(sVersioFitxer) {
console.log('Versió App: '+ sVersioFitxer +', Versió Caché: '+ sVersio);
if (sVersio < (sVersioFitxer || 'v00.0.0000')) {
localStorage['gcf_versio'+ location.pathname] = sVersioFitxer;
location.reload(true);
}
});
}
ฉันเป็นไฟล์เล็ก ๆ ตั้งอยู่ที่ html คือ:
"versio.txt":
v00.5.0014
ฟังก์ชั่นนี้เรียกว่าในทุกหน้าของฉันดังนั้นเมื่อโหลดมันจะตรวจสอบว่าค่าเวอร์ชั่นของ localStorage ต่ำกว่าเวอร์ชั่นปัจจุบันหรือไม่
location.reload(true);
... เพื่อบังคับให้โหลดซ้ำจากเซิร์ฟเวอร์แทนจากแคช
(แน่นอนแทนที่จะเป็น localStorage คุณสามารถใช้คุกกี้หรือที่เก็บข้อมูลไคลเอนต์อื่น ๆ )
ฉันเลือกใช้โซลูชันนี้เพื่อความเรียบง่ายเนื่องจากมีเพียงไฟล์เดียว "versio.txt" ที่จะบังคับให้ไซต์เต็มโหลดใหม่
เมธอด queryString นั้นใช้งานยากและแคช (ถ้าคุณเปลี่ยนจาก v1.1 เป็นเวอร์ชันก่อนหน้านี้จะโหลดจากแคชหมายความว่าแคชไม่ได้ถูกลบทิ้งทำให้รุ่นก่อนหน้าทั้งหมดอยู่ในแคช)
ฉันเป็นมือใหม่เล็ก ๆ น้อย ๆ และฉันจะตรวจสอบและทบทวนการทำงานของคุณอย่างมืออาชีพ
หวังว่ามันจะช่วย
นอกเหนือจากการตั้งค่า Cache-control: no-cache คุณควรตั้งค่าส่วนหัว Expires เป็น -1 หากคุณต้องการให้รีเฟรชสำเนาโลคัลในแต่ละครั้ง (IE บางเวอร์ชันดูเหมือนจะต้องการสิ่งนี้)
ดูแคช HTTP - ตรวจสอบกับเซิร์ฟเวอร์ส่ง If-Modified-Since เสมอ
มีหนึ่งเคล็ดลับที่สามารถใช้ได้เคล็ดลับคือการผนวกพารามิเตอร์ / สตริงเข้ากับชื่อไฟล์ในแท็กสคริปต์และเปลี่ยนเมื่อคุณเปลี่ยนไฟล์
<script src="myfile.js?version=1.0.0"></script>
เบราว์เซอร์ตีความสตริงทั้งหมดเป็นพา ธ ไฟล์แม้ว่าจะเกิดอะไรขึ้นหลังจาก "?" เป็นพารามิเตอร์ ดังนั้นสิ่งที่เกิดขึ้นตอนนี้คือครั้งต่อไปเมื่อคุณอัปเดตไฟล์ของคุณเพียงแค่เปลี่ยนหมายเลขในแท็กสคริปต์บนเว็บไซต์ของคุณ (ตัวอย่าง<script src="myfile.js?version=1.0.1"></script>
) และเบราว์เซอร์ผู้ใช้แต่ละคนจะเห็นไฟล์ที่มีการเปลี่ยนแปลงและคว้าสำเนาใหม่
บังคับให้เบราว์เซอร์ลบแคชหรือโหลดข้อมูลที่ถูกต้องใหม่หรือไม่ ฉันได้ลองวิธีแก้ปัญหาส่วนใหญ่ที่อธิบายไว้ใน stackoverflow งานบางอย่าง แต่หลังจากผ่านไปครู่หนึ่งมันก็จะแคชในที่สุดและแสดงสคริปต์หรือไฟล์ที่โหลดไว้ก่อนหน้า มีวิธีอื่นที่จะล้างแคช (css, js ฯลฯ ) และใช้งานได้จริงบนเบราว์เซอร์ทั้งหมดหรือไม่
ฉันพบจนถึงว่าทรัพยากรที่เฉพาะเจาะจงสามารถโหลดใหม่เป็นรายบุคคลหากคุณเปลี่ยนวันที่และเวลาในไฟล์ของคุณบนเซิร์ฟเวอร์ "การล้างแคช" ไม่ใช่เรื่องง่ายอย่างที่ควรจะเป็น แทนที่จะล้างแคชบนเบราว์เซอร์ของฉันฉันรู้ว่า "การสัมผัส" ไฟล์เซิร์ฟเวอร์แคชจะเปลี่ยนวันที่และเวลาของไฟล์ต้นฉบับที่แคชบนเซิร์ฟเวอร์ (ทดสอบบน Edge, Chrome และ Firefox) และเบราว์เซอร์ส่วนใหญ่จะดาวน์โหลดอัตโนมัติมากที่สุด สำเนาใหม่ล่าสุดของ whats บนเซิร์ฟเวอร์ของคุณ (รหัสกราฟิกมัลติมีเดียใด ๆ ด้วย) ฉันขอแนะนำให้คุณคัดลอกสคริปต์ล่าสุดบนเซิร์ฟเวอร์และ"ทำสิ่งที่สัมผัส"ก่อนที่โปรแกรมของคุณจะทำงานดังนั้นมันจะเปลี่ยนวันที่ของไฟล์ปัญหาทั้งหมดของคุณเป็นวันที่และเวลาล่าสุดจากนั้นจะดาวน์โหลดสำเนาใหม่ สู่เบราว์เซอร์ของคุณ:
<?php
touch('/www/sample/file1.css');
touch('/www/sample/file2.js');
?>
ถ้าอย่างนั้น ... โปรแกรมที่เหลือของคุณ ...
ฉันใช้เวลาพอสมควรในการแก้ไขปัญหานี้ (เนื่องจากเบราว์เซอร์จำนวนมากทำงานแตกต่างกับคำสั่งที่แตกต่างกัน แต่พวกเขาทั้งหมดตรวจสอบเวลาของไฟล์และเปรียบเทียบกับสำเนาที่คุณดาวน์โหลดในเบราว์เซอร์ของคุณหากวันและเวลาที่แตกต่างกัน ไม่สามารถไปในทางที่ถูกต้องควรมีวิธีแก้ไขปัญหาที่ใช้งานได้ดีกว่าอยู่เสมอ ขอแสดงความนับถือและตั้งแคมป์ที่มีความสุข โดยวิธีการสัมผัส (); หรือทางเลือกทำงานในภาษาการเขียนโปรแกรมจำนวนมากรวมอยู่ใน javascript bash sh php และคุณสามารถรวมหรือเรียกพวกเขาเป็น html
คุณต้องการล้างแคชหรือตรวจสอบให้แน่ใจว่าหน้าปัจจุบัน (เปลี่ยนแล้ว) ไม่แคชหรือไม่
หากหลังมันควรจะง่ายเหมือน
<META HTTP-EQUIV="Pragma" CONTENT="no-cache">