Как добавить метку времени к файлу javascript в URL-адресе тега <script>, чтобы избежать кеширования

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

он должен быть как

<script type="text/javascript" src="/js/1.js?v=1234455"/>

Как я могу создать и добавить этот номер? Это простая HTML-страница, поэтому возможно использование любого кода, связанного с PHP или JSP.

Ответы

Ответ 1

Метод 1

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

<script type="text/javascript">
(function(){ 
     var randomh=Math.random();
     var e = document.getElementsByTagName("script")[0];
     var d = document.createElement("script");
     d.src = "//site.com/js.js?x="+randomh+"";
     d.type = "text/javascript"; 
     d.async = true;
     d.defer = true;
     e.parentNode.insertBefore(d,e);
 })();
</script>

Метод 2 (комментарий AJZane)

Малое и надежное включение. Вы можете точно увидеть, где запускается JavaScript, и он менее настраиваемый (до точки), чем метод 1.

    <script>document.write("<script type='text/javascript' src='//site.com
    /js.js?v=" + Date.now() + "'><\/script>");</script>

Ответ 2

Вставьте script динамически через document.createElement('script'), а затем, когда вы установите URL-адрес, вы можете использовать new Date().getTime() для добавления дополнительного параметра.

Если вы беспокоитесь о выполнении javascript перед загрузкой script, вы можете использовать обратный вызов onload элемента script (обратите внимание, что есть несколько обручей, которые нужно прыгать для IE)

Ответ 3

Если вы решите использовать даты или случайные числа для добавления в свой URI, вы предоставите конечному пользователю возможность получать один и тот же кэшированный файл и потенциально могут представлять непреднамеренные угрозы безопасности. Явная система управления версиями не будет. Вот почему:

Почему "Случайные" и "Случайные числа" ПЛОХИЕ

Для случайных чисел у вас нет гарантии, что это же случайное число не было сгенерировано и не было предоставлено этому пользователю ранее. Вероятность генерации одной и той же строки выше при меньших наборах "случайных" чисел или плохих алгоритмах, которые дают одни и те же результаты чаще, чем другие. В общем, если вы полагаетесь на случайный метод JavaScript, имейте в виду, что он псевдослучайный, и может иметь последствия для безопасности, если вы пытаетесь полагаться на уникальность, например, на исправление в одном из ваших сценариев для уязвимостей XSS или что-то в этом роде. аналогичный. Мы не хотим, чтобы Джонни обслуживал старый кешированный и непатентованный JS файл с помощью вызова AJAX более не доверенного стороннего сценария в тот день, когда мистер Хакер случайно посетил его.

Почему даты или временные метки тоже плохие, но не такие плохие

Что касается Dates как "уникальных" идентификаторов, JavaScript будет генерировать объект Date со стороны клиента. В зависимости от формата даты ваши шансы на непреднамеренное кэширование могут различаться. Одна дата (20160101) допускает потенциальные проблемы с кэшированием на целый день, поскольку утреннее посещение приводит к foo.js? Date = 20160101, а также посещение вечером. Вместо этого, если вы укажете с точностью до секунды (20160101000000), ваши шансы конечного пользователя, вызывающего тот же параметр GET, уменьшатся, но все еще будут существовать.

Несколько редких, но возможных исключений:

  • Часы сбрасываются (отстают) один раз в год в большинстве часовых поясов

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

  • Автоматическая синхронизация времени в сети, заставляющая ваши часы настраиваться назад на несколько секунд/минут, когда ваше местное время отключено от времени сервера

  • Корректировка настроек часовых поясов во время путешествия (Астронавты на IIS путешествуют через зону каждые несколько минут... пусть не ухудшают свой опыт просмотра: P)

  • Пользователь любит сбрасывать свои системные часы, чтобы связываться с вами

Почему инкрементное или уникальное управление версиями хорошо :)

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

Вы или ваша команда должны быть единственными, кто редактирует ваши JS файлы, поэтому ключевой момент заключается не в том, что ваш файл нужно подавать свежим каждый раз, я просто должен подавать его свежим, когда он меняется. Кэширование браузера не является плохой вещью в вашем случае, но вы должны сообщить конечному пользователю, КОГДА он должен обновить. По сути, когда ваш файл обновляется, вы хотите убедиться, что клиент получает обновленную копию. Благодаря этому вы также получаете дополнительный бонус за возможность возврата к предыдущим версиям кода, не беспокоясь о проблемах кэширования клиента. Единственным недостатком является то, что вам нужно использовать должную осмотрительность, чтобы убедиться, что вы действительно обновите номер версии при обновлении файлов JS. Имейте в виду только то, что что-то не автоматизировано, не означает, что это обязательно плохая практика или плохая форма. Сделайте так, чтобы ваше решение работало для вашей ситуации и имеющихся у вас ресурсов.

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

Автоматическое увеличение версии на стороне клиента с локальным хранилищем

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

<script type="text/javascript">
(function(){
    /**
     * Increment and return the local storage version for a given JavaScript file by name
     * @param  {string} scriptName  Name of JavaScript file to be versioned (including .js file extension)
     * @return {integer}            New incremented version number of file to pass to .js GET parameter
     */
    var incrementScriptVer = function(scriptName){

        var version = parseInt(localStorage.getItem(scriptName));

        // Simple validation that our item is an integer
        if(version > 0){
            version += 1;
        } else {
            // Default to 1
            version = 1;
        }

        localStorage.setItem(scriptName, version);

        return version;
    };

    // Set your scripts that you want to be versioned here
    var scripts = ['foo.js', 'bar.js', 'baz.js'];

    // Loop through each script name and append our new version number
    scripts.map(function(script){
        var currentScriptVer = incrementScriptVer(script);
        document.write("<script language='text/javascript' type='text/javascript' src='http://yoursite.com/path/to/js/" + script + "?version=" + currentScriptVer + " '><\/script>");
    });
})();

</script>

Для полноты картины я упомяну, что если вы преобразуете из старой системы генерирования "случайных" пронумерованных или датированных переменных GET в инкрементную версионную систему, убедитесь, что вы не перешагнете любые случайно сгенерированные имена файлов с помощью новая система управления версиями. Если вы сомневаетесь, добавьте префикс к вашей переменной GET при изменении методов или просто добавьте новую переменную GET все вместе. Пример: "foo.js? Version = my_prefix_121216" или "foo.js? Version = 121216 & version_system = incremental"

Автоматическое управление версиями через вызовы AJAX и другие методы (если возможна бэкэнд-разработка)

Лично мне нравится держаться подальше от локальных вариантов хранения. Если опция доступна, это будет "лучшее" решение. Попробуйте заставить бэкэнд-разработчика создать конечную точку для отслеживания версий файлов JS, вы всегда можете использовать ответ для этой конечной точки, чтобы определить номер версии. Если вы уже используете контроль версий, такой как Git, вы можете при желании, чтобы ваша команда разработчиков Dev Ops связывала ваши версии с версиями коммитов для некоторой довольно приятной интеграции.

Решение jQuery для конечной точки RESTful GET может выглядеть следующим образом:

var script = "foo.js";

// Pretend this endpoint returns a valid JSON object with something like { "version": "1.12.20" }
$.ajax({
  url: "//yoursite.com/path/to/your/file/version/endpoint/" + script
}).done(function(data) {
    var currentScriptVer = data.version;
    document.write("<script language='text/javascript' type='text/javascript' src='http://yoursite.com/path/to/js/" + script + "?version=" + currentScriptVer + " '><\/script>");
});

Ответ 4

Если вы не можете использовать код пользователя на стороне сервера, вы можете использовать метод getScript для этого.

$(document).ready(function(){
  var randomNum = Math.ceil(Math.random() * 999999);
  var jsfile = 'scripts/yourfile.js?v=' + randomNum;
  $.getScript(jsfile, function(data, textStatus, jqxhr) { });
});

Ссылка URL: http://api.jquery.com/jQuery.getScript/

(Пожалуйста, не забудьте отметить как ответ.)

Ответ 5

Загружать скрипты вручную или с помощью jQuery http://api.jquery.com/jQuery.getScript/. Он также предоставляет возможность предотвращения chipping

Ответ 6

Вы можете заменить источник script на это с помощью чистого Javascript

// get first script
var script = document.getElementsByTagName('script')[0]
var new = document.createElement("script");
// add the source with a timestamp
new.src = 'yoursource.js?' + new Date.getTime().toString();
new.type = 'text/javascript'
script.parentNode.insertBefore(new,script);

Ответ 7

Старый пост, но вот один вкладыш:

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

Ответ 8

Заменить регулярное выражение, если оно не буквенно-цифровое Date.prototype.toISOString()

var today = new Date();
"MyFile_" + today.toISOString().replace(/[^\w]/g, "") + ".pdf"

MyFile_20191021T173426146Z.pdf