Kaip priversti naršyklę iš naujo įkelti talpykloje saugomus CSS / JS failus?

Pastebėjau, kad kai kurios naršyklės (ypač „Firefox“ ir „Opera“) labai kruopščiai naudojasi „ .cs“ ir „ .js“ failų talpyklų kopijomis, netgi tarp naršyklės sesijų. kopiją.

Klausimas: koks yra labiausiai elegantiškas būdas priversti naudotojo naršyklę įkelti naują failą, kai jis pasikeitė?

Idealiu atveju, šis sprendimas nebūtų priverstas naršyklę iš naujo įkelti failą kiekvieną kartą apsilankius puslapyje. Aš paskelbsiu savo sprendimą kaip atsakymą, bet aš smalsu, jei kas nors turi geresnį sprendimą, ir aš leisiu jūsų balsams nuspręsti.

Atnaujinti:

Po to, kai čia aptarėme, suradau John Millikin ir da5id sakinį . Pasirodo, kad yra terminas: automatinė versija .

Toliau pateikiau naują atsakymą, kuris yra mano pirminio sprendimo ir Jono pasiūlymo derinys.

Kita SCdF pasiūlyta idėja yra įtraukti į failą suklastotų užklausų eilutę. (Kai kurie „Python“ kodai, skirti automatiškai naudoti laiko žymę kaip manekeno užklausos eilutę, buvo nusiųsti į. Tačiau yra keletas diskusijų, ar naršyklė talpina failą su užklausos eilute. (Atminkite, kad mes norime, kad naršyklė talpintų failą ir naudotų jį būsimiems apsilankymams.

Kadangi neaišku, kas vyksta su manekeno užklausos seka, aš nepritariu šiam atsakymui.

895
23 сент. Kipas nustatytas rugsėjo 23 d 2008-09-23 06:07 '08, 06:07 2008-09-23 06:07
@ 47 atsakymai
  • 1
  • 2

Atnaujinimas: perrašyta, kad pridėti John Millikin ir da5id sakiniai . Šis sprendimas yra parašytas PHP, bet turėtų būti lengvai pritaikomas kitoms kalboms.

2 naujinimas: įjungus Nick Johnson komentarus, kad pradinė reguliarioji išraiška .htaccess gali sukelti problemų su json-1.3.js . Sprendimas yra tik perrašyti, jei pabaigoje yra lygiai 10 skaitmenų. (Nuo 10 iki 9 skaitmenų visi laikrodžiai nuo 2001 9 9 iki 11/20/2286.)

Pirma, mes naudojame šią perrašymo taisyklę .htaccess:

 RewriteEngine on RewriteRule ^(.*)\.[\d]{10}\.(css|js)$ $1.$2 [L] 

Dabar parašome šią PHP funkciją:

 <link rel="stylesheet" href="/css/base.css" type="text/css" /> 

Dėl to:

 <link rel="stylesheet" href=" 

Tokiu būdu jums nereikės keisti nuorodos žymos, o vartotojas visada matys naujausią CSS. Naršyklė galės saugoti CSS failą, tačiau, jei atliksite bet kokius CSS pakeitimus, naršyklė jį matys kaip naują URL, taigi ji nenaudos talpyklos kopijos.

Tai taip pat gali dirbti su vaizdais, piktogramomis ir javascript. Iš esmės viskas, kas nėra dinamiškai sukurta.

423
23 сент. Atsakymą Kipas pateikia rugsėjo 23 d. 2008-09-23 06:07 '08, 06:07 2008-09-23 06:07

Paprasta kliento technologija

Apskritai spartinimas yra geras. Taigi, yra keletas būdų, priklausomai nuo to, ar patys išsprendėte problemą kurdami svetainę, ar bandote valdyti talpyklą gamybos aplinkoje.

Bendrieji svetainės lankytojai neturės tokios pat patirties, kaip ir kuriant svetainę. Kadangi vidutinis lankytojas atvyksta į svetainę rečiau (galbūt tik kelis kartus per mėnesį, jei nesate „Google“ ar „hi5“ tinklas), tada jie mažiau gali turėti failus talpykloje, o tai gali būti pakankamai. Jei norite priversti įtraukti naują versiją į naršyklę, visada galite įtraukti užklausos eilutę į užklausą ir didinti versijos numerį, kai atliekate svarbius pakeitimus:

 <script src="/myJavascript.js?version=4"></script> 

Tai užtikrina, kad kiekvienas gauna naują failą. Tai veikia, nes naršyklė ieško failo URL, kad nustatytų, ar naršyklėje yra kopija. Jei jūsų serveris nėra sukonfigūruotas daryti kažką su užklausos eilute, jis bus ignoruojamas, bet pavadinimas atrodys kaip naujas failas naršyklėje.

Kita vertus, jei kuriate svetainę, nenorite keisti versijos numerio kiekvieną kartą, kai išsaugosite savo plėtros versijos pakeitimus. Tai būtų varginantis.

border=0

Taigi, kurdami svetainę, geras triukas būtų automatiškai generuoti užklausos eilutės parametrą:

 <!-- Development version: --> <script>document.write('<script src="/myJavascript.js?dev=' + Math.floor(Math.random() * 100) + '"\><\/script>');</script> 

Užklausos eilutės įtraukimas į užklausą yra geras būdas ištekliams pakeisti, tačiau paprasta svetainė gali būti nereikalinga. Ir nepamirškite, kad talpykla yra gera.

Taip pat verta pažymėti, kad naršyklė nebūtinai slopina failų saugojimą talpykloje. Naršyklės taiko tokius dalykus, ir paprastai jie atliekami pagal taisykles, išdėstytas HTTP specifikacijoje. Kai naršyklė pateikia užklausą serveriui, dalis atsakymo yra „EXPIRES“ antraštė. Data, nurodanti naršyklei, kiek laiko ji saugoma talpykloje. Kitą kartą, kai naršyklė susiduria su to paties failo prašymu, ji pamatys, kad ji turi kopiją talpykloje ir žiūri į EXPIRES datą, kad nuspręstų, ar ją naudoti.

Taigi patikėkite ar ne, tai iš tikrųjų yra jūsų serveris, todėl ši naršyklės talpykla yra tokia atspari. Galite pritaikyti savo serverio nustatymus ir keisti „EXPIRES“ antraštes, tačiau maža technika, kurią parašiau aukščiau, tikriausiai jums yra daug lengviau. Kadangi talpinimas yra geras, paprastai norite nustatyti šią datą toli į ateitį („Ilgalaikis galiojimo pabaigos galas“) ir naudoti pirmiau nurodytą metodą.

Jei Jus domina išsamesnė informacija apie HTTP ar tai, kaip šie prašymai pateikiami, gera knyga yra „Steve Souders“ aukštos kokybės svetainės. Tai labai geras temos įvadas.

172
23 сент. atsakymą pateikė keparo rugsėjo 23 d 2008-09-23 07:04 '08, 07:04 2008-09-23 07:04

„Apache“ „Google“ mod_pagespeed įskiepis atliks automatinį versijų leidimą. Tai tikrai aptakus.

Ji analizuoja HTML iš savo žiniatinklio serverio išvestį (veikia su PHP, bėgiais, pythonu, statiniu HTML - bet kokiu) ir perrašo nuorodas į CSS, JS, vaizdo failus, todėl jose yra ID kodas. Jis aptarnauja failus su pakeistais URL, turinčiais labai ilgą talpyklos valdymą. Kai failai keičiasi, jis automatiškai pakeičia URL, kad naršyklė juos iš naujo gautų. Tai iš esmės veikia be jokių kodo pakeitimų. Tai netgi sumažins išėjimo kodą.

111
08 апр. Atsakymą pateikė Leopd 08 apr. 2011-04-08 01:26 '11 ne 1:26 2011-04-08 01:26

Vietoj to, kad pakeistumėte versiją rankiniu būdu, rekomenduojame naudoti faktinio CSS failo MD5 maišą.

Taigi jūsų URL rodys

 http://mysite.com/css/[md5_hash_here]/style.css 

Vis dar galite naudoti perrašymo taisyklę, kad išjungtumėte maišos režimą, bet privalumas yra tas, kad dabar galite nustatyti laikinojo įkrovimo politiką „laikinai išsaugoti“, nes jei URL yra tas pats, tai reiškia, kad failas nepasikeitė.

Tada galite parašyti paprastą scenarijų apvalkalą, kuris apskaičiuoja failo maišą ir atnaujins žymę (tikriausiai norite perkelti jį į atskirą failą įtraukimui).

Tiesiog paleiskite šį scenarijų kiekvieną kartą, kai keičiasi CSS ir esate gerai. Naršyklė įkelia failus tik tada, kai jie bus pakeisti. Jei atliekate redagavimą ir jį atšaukiate, nėra skausmo išsiaiškinti, kuri versija jums reikia grįžti, kad lankytojai nebūtų perkrauti.

90
23 сент. atsakymas duotas levik 23 sep . 2008-09-23 16:25 '08 4:25 pm 2008-09-23 16:25

Jūs nežinote, kodėl vaikinai kenčia tiek, kad įgyvendintų šį sprendimą.

Viskas, ką jums reikia padaryti, jei gaunate failą su modifikuotu laiko žyma ir pridėkite jį kaip užklausos eilutę

PHP, norėčiau tai padaryti kaip:

 <link href="mycss.css?v= 

filemtime yra PHP funkcija, kuri grąžina modifikuotą failo laiko žymę.

57
26 янв. atsakymas duotas Phantom007 26 sausio. 2013-01-26 13:53 '13, 13:53, 2013-01-26 13:53

Jūs galite tiesiog įdėti „ ?foo=1234 “ savo „css / js“ importavimo pabaigoje, pakeisdami 1234 reikšmę į norimą. Pažvelkite į SO html šaltinį.

Idėja, ką valgyti Bet kokiu atveju parametrai yra atmesti / ignoruojami, ir jūs galite pakeisti šį skaičių, kai diegiate naują versiją.


Pastaba . Yra keletas argumentų, kaip tai daro įtaką talpyklai. Manau, kad bendroji prasmė yra ta, kad GET prašymai su parametrais arba be jų turėtų būti laikomi talpyklomis, todėl pirmiau minėtas sprendimas turėtų veikti.

Tačiau žiniatinklio serveris negali nuspręsti, ar jis nori laikytis naudotojo naudojamo specifikacijos ir naršyklės dalies, nes jis gali tiesiog eiti tiesiai į priekį ir bet kuriuo atveju paprašyti naujos versijos.

51
23 сент. SCdF atsakymas, pateiktas rugsėjo 23 d 2008-09-23 06:12 '08 6:12 am. 2008-09-23 06:12

Girdėjau, kad tai vadinama „automatiniu versijos valdymu“. Dažniausias būdas yra įtraukti statinį mtime failą kažkur URL ir padalinti jį naudodami perrašymo tvarkykles arba konfesinius URL:

Taip pat žiūrėkite:

38
23 сент. John Millikin atsakymas rugsėjo 23 d 2008-09-23 06:21 '08 6:21 am. 2008-09-23 06:21

30 ar daugiau esamų atsakymų yra puikus patarimas maždaug 2008 m. Tačiau, kai kalbama apie šiuolaikinį vieno puslapio taikymą (SPA), gali būti laikas persvarstyti kai kurias pagrindines prielaidas ... ypač, idėją, kad pageidautina, kad žiniatinklio serveris tarnautų tik vienai, naujausiai failo versijai.

Įsivaizduokite, kad esate naudotojas, turintis M SPA versiją į savo naršyklę:

  • CD-ROM konsolėje įdiegta nauja N programos versija serveryje
  • Jūs /some.template prie SPA, kuris siunčia XHR į serverį, kad gautų /some.template
    • (Jūsų naršyklė neatnaujino puslapio, todėl vis dar naudojate M versiją)
  • Serveris atsako į /some.template turinį - ar norite grąžinti šablono M arba N versiją?

Jei formatas /some.template pakeistas tarp „M“ ir „N“ (arba failas buvo pervadintas arba kažkas kitas) , tikriausiai nenorite, kad šablono N versija būtų siunčiama į seną versiją „M“ . †

Žiniatinklio programos susiduria su šia problema, kai tenkinamos dvi sąlygos:

  • Įkraunant pradinį puslapį ištekliai prašomi asinchroniškai.
  • Taikymo logika siūlo dalykus (kurie gali keistis būsimose versijose) apie išteklių turinį

Kai tik jūsų paraiška turi parodyti kelias versijas lygiagrečiai, talpyklos sprendimas ir „perkrovimas“ tampa nereikšmingi:

  • Įdiekite visus svetainės failus į dir: /v<release_tag_1>/…files… , /v<release_tag_2>/…files…
  • Nustatykite HTTP antraštes naršyklėms, kad išsaugotumėte failus visam laikui.
    • (Arba dar geriau, įdėkite viską į CDN)
  • Atnaujinkite visus <script> ir <link> žymes ir pan., Kad galėtumėte nurodyti šį failą vienoje iš režimų versijų

Šis paskutinis žingsnis skamba sunkiai, nes gali prireikti paskambinti kiekvieno URL serverio ar kliento kodo URL kūrėju. Arba galite tiesiog sumaniai naudoti <base> ir pakeisti dabartinę versiją vienoje vietoje.

† Vienas iš būdų yra agresyvumas, verčiantis naršyklę iš naujo paleisti viską, kai bus išleista nauja versija. Tačiau norint užbaigti bet kokias operacijas, lengviausia palaikyti bent dvi versijas lygiagrečiai: v-current ir v-previous.

21
03 авг. Atsakymą pateikė Michael Kropat 03 rugpjūtis 2015-08-03 23:09 '15 - 23:09 2015-08-03 23:09

Nenaudokite foo.css? versija = 1! Naršyklės neturėtų talpinti URL naudojant „GET“ kintamuosius. Pasak http://www.thinkvitamin.com/features/webapps/serving-javascript-fast , nors „IE“ ir „Firefox“ tai ignoruoja, „Opera“ ir „Safari“ ne! Vietoj to naudokite foo.v1234.css ir naudokite perrašymo taisykles, kad pašalintumėte versijos numerį.

14
23 сент. atsakymą pateikė airrob Sep 23 2008-09-23 09:02 '08 at 9:02 am 2008-09-23 09:02

ASP.NET 4.5 ir naujesnėms versijoms galite naudoti scenarijų rinkinį .

Prašymas http://localhost/MvcBM_time/bundles/AllMyScripts?v=r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81 ? / AllMyScripts V = r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81 Dėl AllMyScripts paketas ir yra daug eilučių tyrimo v = r0sLDicvP58AIXN_mc3QdyVvVj5euZNzdsa2N1PKvb81 pora. Užklausos eilutėje v yra vertės ženklas, kuris yra unikalus identifikatorius, naudojamas talpyklai. Kol paketas nebus pakeistas, programa „ASP.NET“ paprašys „AllMyScripts“ paketo šiuo simboliu. Jei pakete pasikeičia failas, ASP.NET optimizavimo infrastruktūra sukurs naują raktą, užtikrindama, kad naršyklės užklausos dėl paketo gautų naujausią paketą.

Yra ir kitų privalumų derinant, įskaitant geresnį našumą įkeliant pirmąjį puslapį su minimalizavimu.

10
30 сент. atsakymas, kurį pateikė user3738893 30 rugsėjis 2014-09-30 23:11 '14, 11:11 pm 2014-09-30 23:11

„RewriteRule“ reikia mažo „js“ arba „css“ failų atnaujinimo, kuriame pabaigoje yra pabaigos versijos žymėjimas. Pavyzdžiui. JSON-1.3.js.

Aš pridėjau taško kartojimo klasę [^.] Norėdami regex kaip šis .numeris. ignoruojamas.

 RewriteRule ^(.*)\.[^.][\d]+\.(css|js)$ $1.$2 [L] 
9
05 авг. atsakymas, kurį pateikė Nick Johnson, rugpjūčio 5 d 2010-08-05 19:55 '10, 19:55, 2010-08-05 19:55

Įdomus pranešimas. Perskaitę visus čia pateiktus atsakymus kartu su tuo, kad aš niekada neturėjau problemų su „fiktyviomis“ užklausų eilutėmis (kurių aš nesu įsitikinęs, kodėl visi nenoriai naudojasi), manau, kad sprendimas (kuris pašalina apache perrašymo taisyklių poreikį yra ir priimtu atsakymu) yra apskaičiuoti trumpą HASH turinį CSS faile (vietoj datetime failo) kaip manekeno liniją.

Taip bus:

 <link rel="stylesheet" href="/css/base.css?[hash-here]" type="text/css" /> 

Žinoma, duomenų apdorojimo sprendimai taip pat atliekami redaguojant CSS failą, bet manau, kad tai yra CSS failo turinys, o ne datetime failas, todėl kodėl juos reikia sumaišyti?

8
25 июня '09 в 2:20 2009-06-25 02:20 Atsakymą pateikė Michielas birželio 25 d., 09:20, 2009-06-25 02:20

Laravel'e (PHP) galime tai padaryti tokiu aiškiu ir elegantišku būdu (naudojant failo keitimo laiko žymą):

 <script src="{{ asset('/js/your.js?v='.filemtime('js/your.js')) }}"></script> 

Ir panašiai CSS

 <link rel="stylesheet" href="{{asset('css/your.css?v='.filemtime('css/your.css'))}}"> 
8
03 марта '17 в 13:15 2017-03-03 13:15 atsakymą pateikė Kamil Kiełczewski kovo 03 '17, 13:15 2017-03-03 13:15

Čia yra švarus javascript sprendimas.

 (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); } })(); 

Pirmiau bus ieškoma paskutinį kartą, kai naudotojas apsilankė jūsų svetainėje. Jei paskutinis apsilankymas buvo prieš išleisdami naują kodą, jis naudoja location.reload(true) kad priverstų puslapio atnaujinimą iš serverio.

Paprastai tai naudojamas kaip pirmasis scenarijus <head> , todėl jis įvertinamas prieš bet kokį kitą turinį. Jei reikia paleisti iš naujo, naudotojui tai sunku pastebėti.

Naudoju vietinę saugyklą, kad naršyklėje būtų išsaugota naujausia apsilankymo laiko žyma, tačiau jūs galite pridėti slapukus prie mišinio, jei norite paremti senesnes IE versijas.

7
13 янв. Lloyd Banks atsakymas dėl sausio 13 d 2015-01-13 17:46 '15, 17:46, 2015-01-13 17:46

Ačiū, Kipas už puikų sprendimą!

Aš ją išplėčiau, kad galėčiau jį naudoti kaip „Zend_view_Helper“. Kadangi mano klientas atlieka savo puslapį virtualioje šeimininkėje, tai taip pat išplėčiau.

Tikiuosi, kad tai padės ir kitam.

  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; } } } } 

Sveikinimai ir ačiū.

6
07 янв. atsakymą pateikė lony Jan 07 2011-01-07 08:58 '11 at 8:58 2011-01-07 08:58

ASP.NET, aš prisiimsiu tokį sprendimą su išplėstiniais parametrais (debug / release mode, versija):

Tokiu būdu įtraukti Js arba Css failai:

 <script type="text/javascript" src="Scripts/exampleScript<%=Global.JsPostfix%>" /> <link rel="stylesheet" type="text/css" href="Css/exampleCss<%=Global.CssPostfix%>" /> 

„Global.JsPostfix“ ir „Global.CssPostfix“ „Global.asax“ skaičiuojami taip:

 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(); } ... } 
5
03 авг. Ivan Kochurkin atsakymas 03 rug . 2013-08-03 16:28 '13, 16:28, 2013-08-03 16:28

Pavyzdžiui, galite tiesiog pridėti atsitiktinį skaičių su CSS / JS URL

 example.css?randomNo=Math.random() 
5
04 июля '13 в 13:01 2013-07-04 13:01 atsakymą pateikė Ponmudi VN liepos 4 d., 13 val. 13:01 2013-07-04 13:01

Pasakykite, kad turite failą adresu:

 /styles/screen.css 

URI galite pridėti užklausos parametrą su versijos informacija, pavyzdžiui:

 /styles/screen.css?v=1234 

arba galite pridėti versijos informaciją, pavyzdžiui:

 /v/1234/styles/screen.css 

Antrasis metodas IMHO geriau tinka CSS failams, nes jie gali būti susiję su vaizdais, naudojant santykinius URL, o tai reiškia, kad jei nurodote tokį background-image :

 body { background-image: url('images/happy.gif'); } 

jos URL bus veiksmingas:

 /v/1234/styles/images/happy.gif 

Tai reiškia, kad atnaujinant naudojamą versijos numerį serveris tai laikys nauju šaltiniu ir nenaudos talpyklos versijos. Jei naudojate versijos numerį Subversion / CVS / tt tai reiškia, kad bus pastebėti CSS failuose paminėtų vaizdų pakeitimai. Tai neužtikrina pirmoji schema, t.y. URL images/happy.gif apie /styles/screen.css?v=1235 yra /styles/images/happy.gif , kuriame nėra versijos informacijos.

Įdiegiau talpyklą naudojant šį metodą „Java“ servletais ir tiesiog apdorojau užklausas /v/* naudojant servletą, kuris deleguoja pagrindinį šaltinį (t. Y. /styles/screen.css ). Plėtros režimu DefaultServlet antraštes, nurodančias klientui visuomet patikrinti, ar serveryje yra šviežumo ištekliai (paprastai 304, jei deleguojate „Tomcat DefaultServlet o „ .css , „ .js ir kt. режиме развертывания я устанавливал заголовки, которые говорят "кеш навсегда".

5
ответ дан Walter Rumsby 24 сент. '08 в 11:51 2008-09-24 11:51