2008-08-28 4 views
447

В настоящее время мы работаем в частной бета-версии и все еще находимся в процессе принятия довольно быстрых изменений, хотя, очевидно, по мере того, как использование начинает увеличиваться, мы будем замедлять этот процесс. При этом одна проблема, с которой мы сталкиваемся, заключается в том, что после того, как мы выталкиваем обновление с новыми файлами JavaScript, клиентские браузеры все еще используют кешированную версию файла, и они не видят обновления. Очевидно, что при вызове поддержки мы можем просто сообщить им сделать ctrlF5 обновить, чтобы убедиться, что они получают обновленные файлы с сервера, но было бы предпочтительнее обрабатывать это до этого времени.Как заставить клиентов обновлять файлы JavaScript?

Наша настоящая мысль - просто прикрепить номер версии к имени файлов JavaScript, а затем, когда будут сделаны изменения, увеличьте версию скрипта и обновите все ссылки. Это определенно выполняет свою работу, но обновление ссылок на каждую версию может стать громоздким.

Как я уверен, мы не первые, кто имел дело с этим, я подумал, что я выброшу его в сообщество. Как вы обеспечиваете, чтобы клиенты обновляли свой кеш при обновлении кода? Если вы используете метод, описанный выше, используете ли вы процесс, который упрощает изменение?

+2

http: // stackoverflow.com/questions/118884/what-is-a-elegant-way-to-force-browsers-to-reload-cached-css-js-files – understack 2012-01-23 09:50:08

ответ

419

Насколько я знаю, общее решение - добавить ?<version> в ссылку src скрипта.

Например:

<script type="text/javascript" src="myfile.js?1500"></script> 

Я предполагаю, что на данный момент, что не лучший способ, чем найти замены, чтобы увеличить этот «номер версии» во всех тегах сценария?

Возможно, у вас есть система контроля версий для вас? Большинство систем управления версиями имеют возможность автоматически вводить номер версии при регистрации, например.

Это будет выглядеть примерно так:

<script type="text/javascript" src="myfile.js?$$REVISION$$"></script> 

Конечно, всегда есть лучшие решения как this one.

+4

Кто-нибудь знает, игнорирует ли IE7 это? Похоже, что игнорировать прилагаемые данные и использовать кешированный файл, когда я тестирую в представлении сопоставимости IE8. – 2011-01-20 20:18:28

+3

Я всегда знал, что строки запроса представляют собой пару с ключом, как в? Ver = 123. Благодаря! :) – 2012-02-15 11:41:05

+0

Итак, когда вы добавляете более высокую версию javascript, она автоматически загружается в кеш клиента? Или я понимаю это неправильно? – 2013-07-20 14:12:17

1

Мой коллега только что нашел ссылку на этот метод сразу после того, как я опубликовал (со ссылкой на css) по адресу http://www.stefanhayden.com/blog/2006/04/03/css-caching-hack/. Приятно видеть, что другие используют его и, похоже, работают. Я предполагаю, что в настоящее время нет лучшего способа, чем find-replace для увеличения этих «номеров версий» во всех тегах скриптов?

0

Одним из решений является добавление строки запроса с меткой времени в URL-адрес при извлечении ресурса. Это использует тот факт, что браузер не будет кэшировать ресурсы, извлеченные из URL-адресов с строками запросов в них.

Возможно, вы не хотите, чтобы браузер не кэшировал эти ресурсы; скорее всего, вы хотите, чтобы они были кэшированы, но вы хотите, чтобы браузер извлекал новую версию файла, когда он становится доступным.

Наиболее распространенным решением является встроенная метка времени или номер версии в самом имени файла. Это немного больше, потому что ваш код необходимо изменить, чтобы запросить правильные файлы, но это означает, что, например, версии 7 вашего snazzy_javascript_file.js (т.snazzy_javascript_file_7.js) кэшируется в браузере до тех пор, пока вы не отпустите версию 8, а затем ваш код изменится на выбор snazzy_javascript_file_8.js.

0

Простейшее решение? Не позволяйте кешу браузера вообще. Добавить текущее время (в мс) в качестве запроса.

(Вы все еще в бета-версии, так что вы можете сделать разумный случай для не оптимизации для повышения производительности. Но YMMV здесь.)

3

Если вы генерируете страницу, которая связывает с JS-файлов простым решением является добавив временную метку последней модификации файла к сгенерированным ссылкам.

Это очень похоже на ответ Хаппи, но работает в системах контроля версий без замены ключевых слов. Это также лучше, чем добавлять текущее время, поскольку это предотвратит кеширование, даже если файл не изменился вообще.

65

Добавление текущего времени в URL-адрес действительно является общим решением. Однако вы также можете управлять этим на уровне веб-сервера, если хотите. Сервер может быть настроен для отправки разных HTTP-заголовков для файлов javascript.

Например, чтобы заставить файл быть в кэше не более чем на 1 день, вы бы отправить:

Cache-Control: max-age=86400, must-revalidate 

Для бета, если вы хотите, чтобы заставить пользователя всегда получить последнюю, вы бы использование:

Cache-Control: no-cache, must-revalidate 
16

Не все файлы кеша кеша с '?' в этом. Что я сделал, чтобы убедиться, что он был кэширован как можно больше, я включил версию в имя файла.

Таким образом, вместо stuff.js? 123, я сделал stuff_123.js

Я использовал mod_redirect (я думаю) в апача, чтобы иметь вещи _ *. JS пойти stuff.js

0

Преимущество использование file.js?V=1 по fileV1.js состоит в том, что вам не нужно хранить несколько версий файлов JavaScript на сервере.

Проблема, которую я вижу с file.js?V=1, заключается в том, что у вас может быть зависимый код в другом файле JavaScript, который прерывается при использовании новой версии библиотечных утилит.

Для обратной совместимости, я думаю, что лучше использовать jQuery.1.3.js для ваших новых страниц и позволить существующим страницам использовать jQuery.1.1.js, пока вы не будете готовы обновить старые страницы, если это необходимо.

1

Используйте переменную GET, чтобы предотвратить кеширование браузера.

Добавление ?v=AUTO_INCREMENT_VERSION в конец вашего URL-адреса предотвращает кеширование браузера - избегает любых кешированных скриптов.

38

Google Page-Speed: не включать строку запроса в URL-адрес для статических ресурсов. Большинство прокси, в особенности Squid до версии 3.0, не кэшируют ресурсы с помощью «?» в URL-адресе, даже если в ответе присутствует общий заголовок Cache-control: public. Чтобы включить кэширование прокси для этих ресурсов, удалите строки запросов из ссылок на статические ресурсы и вместо этого запишите параметры в имена файлов.

В этом случае, вы можете включить версию в URL Пример: http://abc.com/v1.2 /script.js и использовать апачский mod_rewrite для перенаправления ссылки на http://abc.com/script.js. При изменении версии клиентский браузер обновит новый файл.

1

Athough это рамки конкретных, Django 1.4 имеет this functionailty, который работает аналогичным образом в связи с 'greenfelt' сайта в above answer

1

В PHP:

function latest_version($file_name){ 
    echo $file_name."?".filemtime($_SERVER['DOCUMENT_ROOT'] .$file_name); 
} 

В HTML:

<script type="text/javascript" src="<?php latest_version('/a-o/javascript/almanacka.js'); ?>">< /script> 

Как это работает:

В HTML напишите filepath и назовите его, как вы это сделали, но только в функции. PHP получает filetime файла и возвращает filepath+name+"?"+time последнего изменения

5

Для ASP.NET Я предполагаю следующее решение с расширенными возможностями (режим отладки/выпуска, версии):

Js или Css файлов, включенных такие путь:

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

Global.JsPostfix и Global.CssPostfix рассчитывается следующим образом в Global.asax:

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

Для страниц ASP.NET Я использую следующий

ДО

<script src="/Scripts/pages/common.js" type="text/javascript"></script> 

после того, как (сила перезарядка)

<script src="/Scripts/pages/common.js?ver<%=DateTime.Now.Ticks.ToString()%>" type="text/javascript"></script> 

Добавление DateTime.Now.Ticks работает очень хорошо ,

32

Этот ответ только на 6 лет опоздал, но я не вижу этого ответа во многих местах ... HTML5 представил Application Cache, который используется для решения этой проблемы. Я обнаружил, что новый код сервера, который я писал, разбивал старый javascript, хранящийся в браузерах людей, поэтому я хотел найти способ истечения срока действия своего javascript. Используйте файл манифеста, который выглядит следующим образом:

CACHE MANIFEST 
# Aug 14, 2014 
/mycode.js 

NETWORK: 
* 

и создать этот файл с новым штампом времени каждый раз, когда вы хотите пользователей обновлять свой кэш. Как примечание, если вы добавите это, браузер будет не перезагрузить (даже если пользователь обновляет страницу), пока манифест не сообщит об этом.

2

Функция jQuery getScript также может использоваться, чтобы гарантировать, что файл js действительно загружается каждый раз при загрузке страницы.

Это, как я это сделал:

$(document).ready(function(){ 
    $.getScript("../data/playlist.js", function(data, textStatus, jqxhr){ 
     startProgram(); 
    }); 
}); 

Проверьте функцию на http://api.jquery.com/jQuery.getScript/

По умолчанию $ .getScript() устанавливает настройки кэша ложны. Это добавляет временный параметр запроса к URL-адресу запроса, чтобы гарантировать, что браузер загружает скрипт каждый раз, когда он запрашивается.

24

Как насчет добавления файла в качестве параметра загрузки?

<script type='text/javascript' src='path/to/file/mylibrary.js?filever=<?=filesize('path/to/file/mylibrary.js')?>'></script> 

Таким образом, каждый раз, когда вы обновляете файл, изменяется параметр «filever».

Как насчет того, когда вы обновляете файл и результаты обновления в том же размере? Каковы шансы?

1

Один простой способ. Edit Htaccess

RewriteEngine On 
RewriteBase/
RewriteCond %{REQUEST_URI} \.(jpe?g|bmp|png|gif|css|js|mp3|ogg)$ [NC] 
RewriteCond %{QUERY_STRING} !^(.+?&v33|)v=33[^&]*(?:&(.*)|)$ [NC] 
RewriteRule^%{REQUEST_URI}?v=33 [R=301,L] 
1

Cache Разорение в ASP.NET Ядра с помощью помощника тега будет обрабатывать это для вас и позволит ваш браузер не держать кэшированные скрипты/CSS до изменения файла. Просто добавьте вспомогательную тег АСП-конкатенирующую версию = «истинную» в скрипт (JS) или ссылку (CSS) тег:

<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true"/> 

Dave Paquette имеет хороший пример и объяснение кэша перебора здесь (внизу страницы) Cache Busting

1

Мы создали SaaS для пользователей и предоставили им сценарий для прикрепления на странице своего сайта, и было невозможно прикрепить версию со сценарием, поскольку пользователь присоединяет скрипт к своему сайту для функциональности и я не могу заставить их изменять версию каждый раз, когда мы обновляем скрипт

Итак, мы нашли способ загрузить n Кувшин версия сценария каждый раз, когда пользователь вызывает оригинальный сценарий

ссылка сценарий предоставляется пользователю

<script src="https://thesaasdomain.com/somejsfile.js" data-ut="user_token"></script> 

Файл сценария

if($('script[src^="https://thesaasdomain.com/somejsfile.js?"]').length !== 0) { 
    init(); 
} else { 
    loadScript("https://thesaasdomain.com/somejsfile.js?" + guid()); 
} 

var loadscript = function(scriptURL) { 
    var head = document.getElementsByTagName('head')[0]; 
    var script = document.createElement('script'); 
    script.type = 'text/javascript'; 
    script.src = scriptURL; 
    head.appendChild(script); 
} 

var guid = function() { 
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { 
     var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); 
     return v.toString(16); 
    }); 
} 

var init = function() { 
    // our main code 
} 

Объяснение:

Пользователь имеет attac hed скрипт, предоставленный им на их веб-сайте, и мы проверили наличие уникального токена, прикрепленного к скрипту, или не используя селектор jQuery, и если он не загружается динамически новым маркером (или версией)

Это вызов того же скрипта в два раза, которые могут быть проблемы с производительностью, но это действительно решает проблему заставить скрипт не загружать из кэша, не помещая версию в реальной ссылке скрипт данного пользователя или клиента

Отказ от ответственности: не используйте если производительность является большой проблемой в вашем случае.

Смежные вопросы