Jak zmusić przeglądarkę do ponownego załadowania buforowanych plików CSS/JS?


Zauważyłem, że niektóre przeglądarki (zwłaszcza Firefox i Opera) bardzo gorliwie używają kopii plików w pamięci podręcznej

.css

i

.js
, nawet między sesjami przeglądarki. Powoduje to problem z aktualizacją jednego z tych plików, ale przeglądarka użytkownika nadal używa kopii z pamięci podręcznej.
Pytanie brzmi: jaki jest najbardziej elegancki sposób, aby zmusić przeglądarkę użytkownika do ponownego załadowania pliku po zmianie?
Idealnie byłoby, gdyby to rozwiązanie nie zmuszało przeglądarki do ponownego ładowania pliku za każdym razem, gdy odwiedzana jest strona. Jako odpowiedź zamieszczę własne rozwiązanie, ale zastanawiam się, czy ktoś ma lepsze rozwiązanie i pozwolę zdecydować twoim głosom.

Aktualizacja

:
Po tym, jak pozwoliłem sobie na chwilę porozmawiać tutaj, znalazłem sugestię

John Millikin

i

da5id

przydatny. Okazuje się, że jest na to termin:

automatyczna kontrola wersji

.
Poniżej zamieściłem nową odpowiedź, będącą połączeniem mojego oryginalnego rozwiązania i sugestii Johna.
Inny pomysł zaproponowany przez

SCdF
, polega na dodaniu fikcyjnego ciągu zapytania do pliku. (Przedstawiono kod Pythona, który automatycznie używa znacznika czasu jako fikcyjnego ciągu zapytania

pi
.). Istnieje jednak dyskusja na temat tego, czy przeglądarka będzie buforować plik z ciągiem zapytania. (Pamiętaj, chcemy, aby przeglądarka buforowała plik i używała go podczas przyszłych wizyt. Chcemy, aby pobierała plik ponownie tylko wtedy, gdy ulegnie zmianie).
Ponieważ nie jest jasne, co się dzieje z fałszywym ciągiem zapytania, nie akceptuję tej odpowiedzi.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:


Aktualizacja:

przepisany z uwzględnieniem sugestii

John Millikin

i

da5id
... To rozwiązanie jest napisane w PHP, ale powinno być łatwe do dostosowania do innych języków.

Aktualizacja 2:

włączenie komentarzy od

Nick Johnson

że oryginalne wyrażenie regularne
.htaccess
może powodować problemy z plikami takimi jak
json-1.3.js
. Rozwiązaniem jest przepisanie tylko wtedy, gdy na końcu jest dokładnie 10 cyfr. (Ponieważ 10 cyfr obejmuje wszystkie znaczniki czasu od 9/9/2001 do 20 11/2286).
Najpierw używamy następującej reguły przepisywania w pliku .htaccess:
RewriteEngine on
RewriteRule ^(.*)\.[\d]{10}\.(css|js)$ $1.$2 [L]

Piszemy teraz następującą funkcję PHP:
<pre class="lang-php prettyprint-override">
/**
* Given a file, i.e./css/base.css, replaces it with a string containing the
* file's mtime, i.e./css/base.1221534296.css.
*
* @param $file The file to be loaded. Must be an absolute path (i.e.
* starting with slash).
*/
function auto_version($file)
{
if(strpos($file, '/') !== 0 || !file_exists($_SERVER['DOCUMENT_ROOT'] . $file))
return $file; $mtime = filemtime($_SERVER['DOCUMENT_ROOT'] . $file);
return preg_replace('{\\.([^./]+)$}', ".$mtime.\$1", $file);
}

Teraz, gdziekolwiek włączysz swój CSS, zmień go z tego:
<link rel="stylesheet" href="/css/base.css" type="text/css"/>

Do teraz:
<link rel="stylesheet" href="<?php echo auto_version('/css/base.css'); ?>" type="text/css"/>

W ten sposób już nigdy nie będziesz musiał zmieniać tagu linku, a użytkownik zawsze zobaczy najnowszą wersję CSS. Przeglądarka będzie mogła buforować plik CSS, ale kiedy wprowadzisz jakiekolwiek zmiany w swoim CSS, przeglądarka zobaczy go jako nowy adres URL, więc nie użyje kopii z pamięci podręcznej.
Może również współpracować z obrazami, ikonami ulubionych i JavaScript. Zasadniczo wszystko, co nie jest generowane dynamicznie.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:


Prosta technika po stronie klienta

Ogólnie buforowanie jest dobre. Jest więc kilka metod, w zależności od tego, czy rozwiązujesz problem samodzielnie podczas tworzenia witryny internetowej, czy próbujesz kontrolować pamięć podręczną w środowisku produkcyjnym.
Zwykli użytkownicy Twojej witryny nie będą mieli takich samych wrażeń jak Ty podczas projektowania witryny. Ponieważ przeciętny użytkownik odwiedza witrynę rzadziej (może tylko kilka razy w miesiącu, jeśli nie należysz do Google ani sieci hi5), jest mniej prawdopodobne, że będą mieć Twoje pliki w pamięci podręcznej, a to może wystarczyć. Jeśli chcesz wymusić nową wersję w przeglądarce, zawsze możesz dodać ciąg zapytania do żądania i zwiększyć numer wersji podczas wprowadzania większych zmian:
<script src="/myJavascript.js?version=4"></script>

Dzięki temu każdy otrzyma nowy plik. Działa to, ponieważ przeglądarka sprawdza adres URL pliku, aby określić, czy ma on kopię w pamięci podręcznej. Jeśli twój serwer nie jest skonfigurowany do robienia czegokolwiek z ciągiem zapytania, zostanie zignorowany, ale nazwa pojawi się jako nowy plik w przeglądarce.
Z drugiej strony, jeśli tworzysz witrynę internetową, nie chcesz zmieniać numeru wersji za każdym razem, gdy zapisujesz zmiany w wersji rozwojowej. Byłoby to męczące.
Dlatego podczas tworzenia witryny dobrą sztuczką byłoby automatyczne generowanie parametru ciągu zapytania:
<!-- Development version: -->
<script>document.write('<script src="/myJavascript.js?dev=' + Math.floor(Math.random() * 100) + '"\><\/script>');</script>

Dodanie ciągu zapytania do żądania jest dobrym sposobem na utworzenie wersji zasobu, ale w przypadku prostej witryny sieci Web może nie być konieczne. I pamiętaj, buforowanie to dobra rzecz.
Warto również zauważyć, że przeglądarka niekoniecznie oszczędza na przechowywaniu plików w pamięci podręcznej. Przeglądarki mają zasady dotyczące tego rodzaju rzeczy i zwykle działają zgodnie z regułami określonymi w specyfikacji HTTP. Gdy przeglądarka wysyła żądanie do serwera, częścią odpowiedzi jest nagłówek EXPIRES .. data, która mówi przeglądarce, jak długo powinna przechowywać ją w pamięci podręcznej. Następnym razem, gdy przeglądarka napotka żądanie dotyczące tego samego pliku, widzi, że ma kopię w pamięci podręcznej i sprawdza datę EXPIRES, aby zdecydować, czy go użyć.
Więc wierz lub nie, to w rzeczywistości Twój serwer sprawia, że ​​pamięć podręczna przeglądarki jest tak trwała. Możesz dostosować ustawienia serwera i zmienić nagłówki EXPIRES, ale mała technika, którą napisałem powyżej, jest prawdopodobnie znacznie łatwiejsza. Ponieważ buforowanie jest dobre, zwykle chcesz ustawić tę datę daleko w przyszłości („nagłówek wygaśnięcia w dalekiej przyszłości”) i użyć techniki opisanej powyżej, aby wymusić zmianę.
Jeśli interesuje Cię więcej informacji o HTTP lub sposobie wysyłania takich żądań, dobrą książką jest Witryny internetowe o wysokiej wydajności Steve'a Soudersa. To bardzo dobre wprowadzenie do tematu.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Podłącz

mod_pagespeed
http://code.google.com/p/modpagespeed/
z google dla apache zrobi za Ciebie automatyczne przechowywanie wersji. Jest naprawdę śliski.
Analizuje HTML w swojej ścieżce z serwera WWW (działa z PHP, railsami, pythonem, statycznym HTML - czymkolwiek) i przepisuje linki do CSS, JS, plików graficznych, aby zawierały kod id. Obsługuje pliki w zmodyfikowanych adresach URL z bardzo długimi kontrolkami pamięci podręcznej. Gdy pliki się zmieniają, automatycznie zmienia adresy URL, więc przeglądarka musi je ponownie pobrać. Po prostu działa, bez żadnych zmian w kodzie. Zminimalizuje nawet Twój kod wyjściowy.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Zamiast ręcznie zmieniać wersję, zalecałbym użycie skrótu MD5 rzeczywistego pliku CSS.
Więc twój adres URL będzie miał postać
[url=http://mysite.com/css/]http://mysite.com/css/[/url][md5_hash_here]/style.css

Nadal możesz użyć reguły przepisywania, aby usunąć skrót, ale zaletą jest to, że możesz teraz ustawić zasady pamięci podręcznej na buforowanie na zawsze, ponieważ jeśli adres URL pozostaje taki sam, oznacza to, że plik pozostaje ten sam.
Następnie możesz napisać prosty skrypt powłoki, który oblicza hash pliku i aktualizuje tag (prawdopodobnie chcesz przenieść go do osobnego pliku, aby dołączyć).
Po prostu uruchamiaj ten skrypt za każdym razem, gdy zmieni się CSS i wszystko będzie dobrze. Przeglądarka przeładuje pliki TYLKO wtedy, gdy zostaną zmienione. Jeśli edytujesz, a następnie cofniesz, możesz łatwo dowiedzieć się, do której wersji należy powrócić, aby odwiedzający nie pobierali jej ponownie.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Nie jestem pewien, dlaczego tak trudno wam wdrożyć tę decyzję.
Wszystko, co musisz zrobić, to pobrać zmodyfikowany plik znacznika czasu i dodać go jako ciąg zapytania do pliku
W roku PHP zrobiłbym to tak:
<link href="mycss.css?v=<?= filemtime('mycss.css') ?>" rel="stylesheet">

filemtime to funkcja PHP, która zwraca zmodyfikowany plik znacznika czasu.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz po prostu umieścić
? Foo = 1234
na końcu importu css/js, zmieniając 1234 na cokolwiek chcesz. Spójrz na źródło html SO jako przykład.
Czy to jest pomysł? parametry są i tak odrzucane/ignorowane w żądaniu i możesz zmienić tę liczbę podczas wdrażania nowej wersji.

Uwaga:

istnieje pewien argument dotyczący tego, jak dokładnie wpływa to na buforowanie. Uważam, że generalnie chodzi o to, że żądania GET, z parametrami lub bez,

powinien

być buforowalne, więc powyższe rozwiązanie powinno działać.
Zależy to jednak zarówno od serwera WWW, który zdecyduje, czy chce zastosować się do tej części specyfikacji, jak i od przeglądarki, z której korzysta użytkownik, ponieważ i tak może po prostu poprosić o nową wersję.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Słyszałem, że nazywa się to „automatycznym wersjonowaniem”. Najpopularniejszą metodą jest umieszczenie statycznego pliku mtime gdzieś w adresie URL i usunięcie go za pomocą programów obsługi przepisywania lub konfiguracji adresu URL:
Zobacz też:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Około 30 istniejących odpowiedzi to świetne rady dla witryny internetowej około 2008 roku. Jednak jeśli chodzi o nowoczesne

aplikacja jednostronicowa

(SPA), być może nadszedł czas, aby powrócić do niektórych fundamentalnych założeń ... w szczególności idei, że pożądane jest, aby serwer sieciowy obsługiwał tylko jedną, najnowszą wersję pliku.
Wyobraź sobie, że jesteś użytkownikiem, którego wersja to

M

SPA załadowane do Twojej przeglądarki:
  • Na dysku CD z potokiem zostanie wdrożona nowa wersja z aplikacji na serwer
  • Poruszasz się w obrębie SPA, które przesyła XHR do serwera, aby otrzymać
    /some.template
    [list][*](Twoja przeglądarka nie odświeżyła strony, więc nadal używasz wersji M )

[/*]
[*]
Serwer odpowiada treścią
/some.template
- chcesz, aby zwrócił wersję

M

lub

N

szablon?
[/*]
[/list]
Jeśli format
/some.template
uległ zmianie między wersjami

M

i

N

(lub nazwa pliku została zmieniona lub cokolwiek innego),

prawdopodobnie nie chcesz tej wersji

N

szablon został wysłany do przeglądarki działającej w starej wersji

M

analizator

.†
Aplikacje internetowe napotykają ten problem, gdy spełnione są dwa warunki:
  • Zasoby są żądane asynchronicznie jakiś czas po załadowaniu strony początkowej
  • Logika aplikacji zakłada, że ​​zawartość zasobów może ulec zmianie w przyszłych wersjach

Gdy aplikacja będzie musiała obsługiwać wiele wersji równolegle,

rozwiązanie problemu buforowania i „przeładowywania” staje się trywialne

:
  • Zainstaluj wszystkie pliki serwisu w wersjonowanych katalogach:
    / v & < release_tag_1 & >/… files…
    ,
    / v & < release_tag_2 & >/… files…
  • Ustaw nagłówki HTTP, aby przeglądarki mogły na zawsze buforować pliki [list][*](Lub jeszcze lepiej, umieść wszystko na CDN)

[/*]
[*]
Zaktualizuj wszystkie tagi
& < script & >
i
& < link & >
itp. wskazać ten plik w jednym z wersjonowanych katalogów
[/*]
[/*][/list]
Ten ostatni krok wydaje się trudny, ponieważ może wymagać wywołania narzędzia do tworzenia adresów URL dla każdego adresu URL w kodzie po stronie serwera lub klienta. Lub możesz po prostu mądrze używać

etykietka
https://developer.mozilla.org/ ... /base
& < base & >
i zmień aktualną wersję w jednym miejscu.
† Jednym ze sposobów obejścia tego problemu jest agresywne działanie i zmuszanie przeglądarki do ponownego załadowania wszystkiego, gdy pojawi się nowa wersja. Aby jednak umożliwić ukończenie dowolnej oczekującej operacji, nadal może być łatwiej utrzymać równolegle co najmniej dwie wersje: v-current i v-previous.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Nie używaj foo.css? Version = 1! Przeglądarki nie powinny buforować adresów URL za pomocą zmiennych GET. Według

http://www.thinkvitamin.com/fe ... -fast
http://www.thinkvitamin.com/fe ... -fast
podczas gdy IE i Firefox ignorują to, Opera i Safari nie! Zamiast tego użyj foo.v1234.css i użyj reguł przepisywania, aby usunąć numer wersji.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

W Laravel (PHP) możemy to zrobić w następujący przejrzysty i elegancki sposób (wykorzystując modyfikację pliku znacznika czasu):
<script src="{{ asset('/js/your.js?v='.filemtime('js/your.js')) }}"></script>

Podobnie jest z CSS
<link rel="stylesheet" href="{{asset('css/your.css?v='.filemtime('css/your.css'))}}">
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

RewriteRule wymaga niewielkiej aktualizacji dla plików js lub css, które na końcu zawierają kropkę wersji. Na przykład. json-1.3.js.
Dodałem klasę negacji kropek [^.] By regex so .number. ignorowane.
RewriteRule ^(.*)\.[^.][\d]+\.(css|js)$ $1.$2 [L]
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Oto czyste rozwiązanie JavaScript
(function(){// Match this timestamp with the release of your code
var lastVersioning = Date.UTC(2014, 11, 20, 2, 15, 10); var lastCacheDateTime = localStorage.getItem('lastCacheDatetime'); if(lastCacheDateTime){
if(lastVersioning > lastCacheDateTime){
var reload = true;
}
} localStorage.setItem('lastCacheDatetime', Date.now()); if(reload){
location.reload(true);
}})();

Powyższe będzie wyglądało jak ostatnia wizyta użytkownika w Twojej witrynie. Jeśli ostatnia wizyta miała miejsce przed opublikowaniem nowego kodu, używa on
location.reload (true)
, aby wymusić odświeżenie strony z serwera.
Zwykle mam ten pierwszy skrypt w
& < head & >
, więc jest sprawdzany przed załadowaniem jakiejkolwiek innej zawartości. Jeśli nastąpi ponowne uruchomienie, jest to ledwo zauważalne dla użytkownika.
Używam pamięci lokalnej do przechowywania ostatniego znacznika czasu odwiedzonego w przeglądarce, ale możesz dodać pliki cookie do miksu, jeśli chcesz obsługiwać starsze wersje IE.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

W przypadku ASP.NET 4,5 i nowszych można użyć

skrypty pakowania
http://www.asp.net/mvc/tutoria ... ation
.

Żądanie
http:// localhost/MvcBM_time/bundles/AllMyScripts? V = r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81
dotyczy pakietu AllMyScripts i zawiera kilka linii zapytań v = r0sL58Dic Łańcuch zapytania v ma token wartości, który jest unikalnym identyfikatorem używanym do buforowania. Do momentu zmiany pakietu aplikacja ASP.NET będzie żądać pakietu AllMyScripts przy użyciu tego tokenu. Jeśli jakikolwiek plik w pakiecie ulegnie zmianie, platforma optymalizacji ASP.NET generuje nowy token, zapewniając, że żądania przeglądarki dotyczące pakietu otrzymają najnowszy pakiet.

Istnieją inne zalety łączenia, w tym zwiększona wydajność podczas ładowania pierwszej strony przy użyciu minifikacji.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Ciekawy post. Po przeczytaniu wszystkich odpowiedzi tutaj, w połączeniu z faktem, że nigdy nie miałem żadnych problemów z „fałszywymi” ciągami zapytań (których nie jestem pewien, dlaczego wszyscy tak niechętnie z tego korzystają), myślę, że rozwiązanie (które usuwa potrzeba przepisania reguł apache jak w zaakceptowanej odpowiedzi) polega na obliczeniu krótkiego HASH zawartości pliku CSS (zamiast pliku z datą i godziną) jako fikcyjnego ciągu zapytania.
Doprowadziłoby to do następujących wyników:
<link rel="stylesheet" href="/css/base.css?[hash-here]" type="text/css"/>

Oczywiście rozwiązania datetime również działają w przypadku edycji pliku CSS, ale myślę, że chodzi o zawartość pliku css, a nie pliku z datetime, więc po co je mieszać?
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Uważam, że Chrome ma świetne rozwiązanie dla mojego rozwoju.
https://developer.chrome.com/d ... 3hard reboot
https://developer.chrome.com/d ... eload
Gdy narzędzia programistyczne są otwarte, po prostu naciśnij przycisk Odśwież i zwolnij go, gdy tylko najedziesz kursorem na opcję „Opróżnij pamięć podręczną i mocno załaduj”.
To mój najlepszy przyjaciel i jest to super łatwy sposób na zdobycie tego, czego chcesz!
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Dzięki Kip za idealne rozwiązanie!
Rozszerzyłem go, aby używać go jako Zend_view_Helper. Ponieważ mój klient uruchamia swoją stronę na hostingu współdzielonym, rozszerzyłem to również, aby to zrobić.
Mam nadzieję, że to pomoże też komuś innemu.
/**
* Extend filepath with timestamp to force browser to
* automatically refresh them if they are updated
*
* This is based on Kip's version, but now
* also works on virtual hosts
* @link [url=http://stackoverflow.com/questions/118884/what-is-an-elegant-way-to-force-browsers-to-reload-cached-css-js-files]http://stackoverflow.com/quest ... files[/url]
*
* Usage:
* - extend your .htaccess file with
* # Route for My_View_Helper_AutoRefreshRewriter
* # which extends files with there timestamp so if these
* # are updated a automatic refresh should occur
* # RewriteRule ^(.*)\.[^.][\d]+\.(css|js)$ $1.$2 [L]
* - then use it in your view script like
* $this->headLink()->appendStylesheet( $this->autoRefreshRewriter($this->cssPath . 'default.css'));
*
*/
class My_View_Helper_AutoRefreshRewriter extends Zend_View_Helper_Abstract { public function autoRefreshRewriter($filePath) { if (strpos($filePath, '/') !== 0) {// path has no leading '/'
return $filePath;
} elseif (file_exists($_SERVER['DOCUMENT_ROOT'] . $filePath)) {// file exists under normal path
// so build path based on this
$mtime = filemtime($_SERVER['DOCUMENT_ROOT'] . $filePath);
return preg_replace('{\\.([^./]+)$}', ".$mtime.\$1", $filePath);
} else {// fetch directory of index.php file (file from all others are included)
// and get only the directory
$indexFilePath = dirname(current(get_included_files()));// check if file exist relativ to index file
if (file_exists($indexFilePath . $filePath)) {// get timestamp based on this relativ path
$mtime = filemtime($indexFilePath . $filePath);// write generated timestamp to path
// but use old path not the relativ one
return preg_replace('{\\.([^./]+)$}', ".$mtime.\$1", $filePath);
} else { return $filePath;
}
}
}}

Twoje zdrowie i dzięki.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Nie znaleziono podejścia DOM po stronie klienta do dynamicznego tworzenia węzła skryptu (lub CSS):
<script>
var node = document.createElement("script");
node.type = "text/javascript";
node.src = 'test.js?'+Math.floor(Math.random()*999999999);
document.getElementsByTagName("head")[0].appendChild(node);
</script>
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Google Chrome ma

twardy reset
, i

pusta pamięć podręczna i twardy restart
... Możesz nacisnąć i przytrzymać przycisk resetowania (w trybie testowym), aby wybrać jeden z nich.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Załóżmy, że masz plik dostępny pod adresem:
/styles/screen.css

możesz dodać parametr zapytania z informacją o wersji do identyfikatora URI, na przykład:
/styles/screen.css?v=1234

lub możesz dodać informacje o wersji, takie jak:
/v/1234/styles/screen.css

IMHO druga metoda jest lepsza dla plików CSS, ponieważ mogą zawierać linki do obrazów przy użyciu względnych adresów URL, co oznacza, że ​​jeśli określisz
background-image
w następujący sposób:
body {
background-image: url('images/happy.gif');
}

jego adres URL byłby skuteczny:
/v/1234/styles/images/happy.gif

Oznacza to, że jeśli zaktualizujesz numer używanej wersji, serwer potraktuje go jako nowy zasób i nie użyje wersji z pamięci podręcznej. Jeśli opierasz swój numer wersji na Subversion/CVS/itp. rewizja, co oznacza, że ​​zmiany w obrazach, do których odwołują się pliki CSS, zostaną zauważone. Nie jest to gwarantowane w przypadku pierwszego schematu, tj. Adres URL
images/happy.gif
względem
/styles/screen.css?v=1235
to
/ styles/images/happy.gif
, który nie zawiera żadnych informacji o wersji.
Zaimplementowałem rozwiązanie buforowania przy użyciu tej techniki z serwletami Java i po prostu obsługuję żądania do
/ v/*
za pomocą serwletu, który deleguje podstawowy zasób (tj.
/ styles/screen. Css ). w trybie programistycznym ustawiłem nagłówki pamięci podręcznej, które mówią klientowi, aby zawsze sprawdzał aktualność zasobu na serwerze (zwykle skutkuje to 304, jeśli delegujesz Tomcat[code]DefaultServlet
i
.css
plik, .js [/code]itp. nie zmienił się), podczas gdy w trybie wdrażania ustawiam nagłówki z napisem „pamięć podręczna na zawsze”.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz wymusić „buforowanie całej sesji”, jeśli dodasz identyfikator sesji jako ukryty parametr w pliku js/css:
<link rel="stylesheet" src="myStyles.css?ABCDEF12345sessionID"/>
<script language="javascript" src="myCode.js?ABCDEF12345sessionID"></script>

Jeśli potrzebujesz buforować całą wersję, możesz dodać kod, aby wydrukować datę pliku lub coś podobnego. Jeśli używasz języka Java, możesz użyć niestandardowego tagu, aby elegancko wygenerować link.
<link rel="stylesheet" src="myStyles.css?20080922_1020"/>
<script language="javascript" src="myCode.js?20080922_1120"></script>
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Dla ASP.NET zakładam następujące rozwiązanie z opcjami zaawansowanymi (tryb debugowania/wydania, wersje):
Pliki Js lub Css zawarte w ten sposób:
<script type="text/javascript" src="Scripts/exampleScript<%=Global.JsPostfix%>"/>
<link rel="stylesheet" type="text/css" href="Css/exampleCss<%=Global.CssPostfix%>"/>

Global.JsPostfix i Global.CssPostfix są obliczane w Global.asax w następujący sposób:
protected void Application_Start(object sender, EventArgs e)
{
...
string jsVersion = ConfigurationManager.AppSettings["JsVersion"];
bool updateEveryAppStart = Convert.ToBoolean(ConfigurationManager.AppSettings["UpdateJsEveryAppStart"]);
int buildNumber = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.Revision;
JsPostfix = "";
#if !DEBUG
JsPostfix += ".min";
#endif
JsPostfix += ".js?" + jsVersion + "_" + buildNumber;
if (updateEveryAppStart)
{
Random rand = new Random();
JsPosfix += "_" + rand.Next();
}
...
}
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Możesz po prostu dodać losową liczbę z adresem URL CSS/JS, takim jak
example.css?randomNo=Math.random()
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Niedawno rozwiązałem ten problem w Pythonie. Oto kod (powinien być łatwy do dostosowania do innych języków):
def import_tag(pattern, name, **kw):
if name[0] == "/":
name = name[1:]
# Additional HTML attributes
attrs = ' '.join(['%s="%s"' % item for item in kw.items()])
try:
# Get the files modification time
mtime = os.stat(os.path.join('/documentroot', name)).st_mtime
include = "%s?%d" % (name, mtime)
# this is the same as sprintf(pattern, attrs, include) in other
# languages
return pattern % (attrs, include)
except:
# In case of error return the include without the added query
# parameter.
return pattern % (attrs, name)def script(name, **kw):
return import_tag("""<script type="text/javascript" """ +\
""" %s src="/%s"></script>""", name, **kw)def stylesheet(name, **kw):
return import_tag('<link rel="stylesheet" type="text/css" ' +\
"""%s href="/%s">', name, **kw)

Ten kod zasadniczo dodaje sygnaturę czasową pliku jako parametr zapytania do adresu URL. Wywołanie następnej funkcji
script("/main.css")

doprowadzi do tego
<link rel="stylesheet" type="text/css" href="/main.css?1221842734">

Zaletą jest oczywiście to, że nigdy więcej nie musisz zmieniać kodu HTML, dotknięcie pliku CSS automatycznie unieważni pamięć podręczną. Działa bardzo dobrze bez zauważalnego obciążenia.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jeśli używasz git + PHP, możesz przeładować skrypt z pamięci podręcznej za każdym razem, gdy nastąpi zmiana w repozytorium git, używając następującego kodu:
exec('git rev-parse --verify HEAD 2>/dev/null', $gitLog);
echo ' <script src="/path/to/script.js"?v='.$gitLog[0].'></script>'.PHP_EOL;
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Jeśli jesteś programistą, który chce uniknąć buforowania, na karcie sieciowej Chrome dostępna jest opcja wyłączenia buforowania. W przeciwnym razie możesz to zrobić bez struktury renderującej serwer, używając dwóch tagów script.
<script type="text/javascript">
document.write('<script type="text/javascript" src="myfile.js?q=' + Date.now() + '">
// can't use myfile.js stuff yet
</script>')
<script type="text/javascript">
// do something with myfile.js
</script>

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się