Как заставить клиентов обновлять файлы JavaScript?

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

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

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

Ответ 1

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

Например:

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

Я предполагаю в этот момент, что нет лучшего способа, чем find-replace для увеличения этих "номеров версий" во всех тегах script?

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

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

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

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

Ответ 2

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

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

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

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

Cache-Control: no-cache, must-revalidate

Ответ 3

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

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

Ответ 4

Это использование было отменено: https://developer.mozilla.org/en-US/docs/Web/HTML/Using_the_application_cache

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

CACHE MANIFEST
# Aug 14, 2014
/mycode.js

NETWORK:
*

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

Ответ 5

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

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

Поэтому каждый раз, когда вы обновляете файл, изменяется параметр "filever".

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

Ответ 6

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

Итак, вместо stuff.js?123 я сделал stuff_123.js

Я использовал mod_redirect (я думаю) в apache для have stuff_*.js для перехода stuff.js

Ответ 7

Для страниц 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 работает очень хорошо.

Ответ 8

Для 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();
    }
    ...
}

Ответ 9

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

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

Ответ 10

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

Вот как я это сделал:

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

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

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

Ответ 11

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

Итак, мы нашли способ загрузить более новую версию script каждый раз, когда пользователь вызывает исходный script

ссылка script, предоставленная пользователю

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

файл 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
}

Объяснение:

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

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

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

Ответ 12

В настоящее время распространенной практикой является генерация хеш-кода контента как часть имени файла, чтобы заставить браузер, особенно IE, перезагружать файлы javascript или файлы css.

Например,

поставщик. a7561fb0e9a071baadb9.js
главный. b746e3eb72875af2caa9.js

Как правило, это работа для таких инструментов построения, как webpack. Вот более подробная информация, если кто-то хочет попробовать, если вы используете webpack.

Ответ 13

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

Ответ 14

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

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

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

Ответ 15

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

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

Ответ 16

Несмотря на то, что в Django 1.4 есть this functionailty, который работает аналогично ссылке на сайт "greenfelt" в ответе

Ответ 17

В 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 последнего изменения

Ответ 18

Cache Busting в ASP.NET Core через помощник тега обработает это для вас и позволит вашему браузеру хранить кешированные скрипты /css до тех пор, пока файл не изменится. Просто добавьте тег helper asp-append-version = "true" в тэг script (js) или ссылку (css):

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

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

Ответ 19

В asp.net mvc вы можете использовать @DateTime.UtcNow.ToString() для номера версии файла js. Номер версии автоматически меняется с датой, и вы заставляете браузер клиентов автоматически обновлять файл js. Я использую этот метод, и это хорошо работает.

<script src="~/JsFilePath/[email protected]()"></script>

Ответ 20

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

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

Ответ 21

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

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

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

Ответ 22

Один простой способ. Изменить 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]

Ответ 23

Ниже работал для меня:

<head>
<meta charset="UTF-8">
<meta http-equiv="cache-control" content="no-cache, must-revalidate, post-check=0, pre-check=0" />
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />
</head>

Ответ 24

location.reload (истина);

см https://www.w3schools.com/jsref/met_loc_reload.asp

Я динамически вызываю эту строку кода, чтобы гарантировать, что javascript был повторно получен с веб-сервера, а не из кэша браузера, чтобы избежать этой проблемы.