Подтвердить что ты не робот

Кэширование jquery getScript

По умолчанию $.getScript() отключает кеширование, и вы можете использовать $.ajaxSetup и установить кеширование в true. При тестировании, если script на самом деле кэшируется с Firebug в большинстве случаев, script возвращается на 200 (что означает, что script - это новая копия), а один, возможно, в 20 или 30 раз, он вернется 304 (что означает, что используется кешированная версия). Почему он получает новую копию подавляющее большинство времени?

$.ajaxSetup({
    cache: true
 });

 $.getScript( scriptFile );

Файлы, которые извлекают getScript, не редактировались, а запросы - это изменение страницы.

4b9b3361

Ответ 1

Произошла ошибка с даты, когда этот вопрос был отправлен, где Firefox и Chrome заявили, что script не загружается из кэша, если это действительно так. На дату этого ответа этот вопрос все еще существует. Самый простой способ проверить - использовать console.log и отправить номер версии.

Для кэширования динамически загруженного script он просто выполняется с использованием следующего кода.

function onDemandScript ( url, callback ) {
    callback = (typeof callback != 'undefined') ? callback : {};

    $.ajax({
         type: "GET",
         url: url,
         success: callback,
         dataType: "script",
         cache: true
     });    
}

Для разработки вы должны прокомментировать кеш: true.

Ответ 2

Сначала давайте выясним, что означает, что jQuery отключает кеширование.

Когда jQuery отключает кеш означает, что принудительно перезагружает файл браузером с помощью какого-то трюка, например, добавив лишнее случайное число как параметр в конце URL.

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

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

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

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

Подводя итоги:
cache:true позволяет обозревателю выбрать для кеша этого файла из отправленного вами заголовка.
cache:false снова заставляет файл загружаться.

Некоторые вопросы относительно кеша:
кеширование файлов JavaScript
Кэш-контроль IIS7

Внутренний код
getScript() вызывает jQuery.get(), ведьма - это сокращенная функция Ajax

$.ajax({
  url: url,
  data: data,
  success: success,
  dataType: dataType
});

Итак, вызывая getScript(), вы делаете вызов ajax, и jQuery не хранит какой-либо кеш ваших файлов, если это то, что вы думаете в первую очередь.

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

function getScriptCcd(url, callback)
{
    jQuery.ajax({
            type: "GET",
            url: url,
            success: callback,
            dataType: "script",
            cache: true
    });
};

Это не влияет на глобальный параметр кеша и загружает файлы script без добавления каких-либо параметров без кэша в конце.

Ответ 3

Я знаю, что это старый пост, и существующий ответ - это реальный ответ, но прикосновение к Iscariot относится к IT REALLY IS CACHING (по крайней мере, своего рода). Это просто причуда firefox. Возможно, это окажется полезным для других, которые смущены этой причудой.

Я тестировал эту концепцию с файлом javascript ДЕЙСТВИТЕЛЬНО БОЛЬШОГО, который определяет полигоны карты google для границ округа Айдахо DOT на основе массивов десятков тысяч лат. (размер несжатого файла составляет 2,806,257, но я запускаю его через процесс сжатия), Используя следующий javascript

// Grab polys if not already loaded
if (typeof(defaults.data.polys) === 'undefined') {
    /*$.getScript('/Scripts/ScriptMaster.php?file=Districts', function () {});*/
    $.ajax({
        type: "GET",
        url: '/Scripts/ScriptMaster.php?file=Districts',
        success: function() {
            defaults.data.polys = getPolys();
            data.polys = defaults.data.polys;
        },
        dataType: "script",
        cache: true
    });
}

и вы можете увидеть соответствующий php (вы не хотите, чтобы фактический файл Districts.js занимал слишком много места на этом посту, поэтому здесь ScriptMaster.php)

<?php
require_once('../settings.php');

if (!isset($_GET['file'])) die();
$file = $_GET['file'];
$doCache = $file == 'Districts';

header('Content-type: application/x-javascript');
if ($doCache) {
    // This is a luxury for loading Districts.js into cache to improve speed
    //  It is at the top because firefox still checks the server for
    //  headers even when it already cached
    $expires = 7 * 60 * 60 * 24; // set cache control to expire in a week (this is not likely to change)
    header('Cache-Control: max-age='.$expires.', must-revalidate');
    header('Last-modified: Fri, 3 May 2013 10:12:37 GMT');
    header('Expires: '.gmdate('D, d M Y H:i:s', time() + $expires).'GMT');
    header('Pragma: public');
}

ob_start("compress");
require_once($file.".js");
ob_end_flush();

function compress($buffer) {
    global $doCache;
    if (DEV_MODE && !$doCache) return $buffer;
    /* remove comments */
        $buffer = preg_replace('/\/\/.+?$/m', '', preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $buffer));
    /* remove tabs, spaces, new lines, etc. */
        $buffer = str_replace(array("\r\n", "\r", "\n", "\t", '  ', '    ', '    '), '', $buffer);
    /* remove unnecessary spaces */
        $buffer = str_replace(': ', ':', $buffer);
        $buffer = str_replace(' :', ':', $buffer);
        $buffer = str_replace(', ', ',', $buffer);
        $buffer = str_replace(' ,', ',', $buffer);
        $buffer = str_replace('; ', ';', $buffer);
        $buffer = str_replace(' ;', ';', $buffer);
        $buffer = str_replace('{ ', '{', $buffer);
        $buffer = str_replace(' {', '{', $buffer);
        $buffer = str_replace('} ', '}', $buffer);
        $buffer = str_replace(' }', '}', $buffer);

    if ($doCache) { header('Content-Length: '.strlen($buffer)); }

    return $buffer;
}
?>

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

Итак, я сделал пять тестовых прогонов, показывающих время загрузки для этого script с ajax, как указано в firebug. Вот результаты

#results loading the script after clearing cache (yes those are seconds, not ms)
200 OK      4.89s
200 OK      4.9s
200 OK      5.11s
200 OK      5.78s
200 OK      5.14s

#results loading the page with control+r
200 OK      101ms
200 OK      214ms
200 OK      24ms
200 OK      196ms
200 OK      99ms
200 OK      109ms

#results loading the page again by navigating (not refreshing)
200 OK      18ms
200 OK      222ms
200 OK      117ms
200 OK      204ms
200 OK      19ms
200 OK      20ms

Как вы можете видеть, мой сервер localhost для подключения к веб-клиенту не самый последовательный, а спецификации моего ноутбука немного потрепанные (одноядерный процессор и все, ему тоже несколько лет). НО ТОЧКА есть значительный время загрузки после загрузки кеша.

[Также в случае, если кому-то любопытно без сжатия script (а не как табуляции, пробелы или новые строки теряются впустую, оно просто должно быть доступно для чтения) занимает от 7-8 секунд до загрузки, но я не собирается сделать это пять раз]

Так что никогда не бойтесь, это действительно кеширование. Честно говоря, для небольших скриптов, которые загружают только MS, вы можете не заметить разницу в firefox; просто потому, что он проверяет заголовки с сервера. Я знаю это из-за изменения времени загрузки от перемещения этих функций заголовка от конца script до начала. Если у вас есть эти функции после прохождения php через строку, загрузка занимает больше времени.

Надеюсь, это поможет!

Ответ 4

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

Сайт jQuery doc имеет приятное расширение для того, чтобы не добавлять временную метку к запросу и обходить кеш:

jQuery.cachedScript = function( url, options ) {

  // Allow user to set any option except for dataType, cache, and url
  options = $.extend( options || {}, {
    dataType: "script",
    cache: true,
    url: url
  });


  // Use $.ajax() since it is more flexible than $.getScript
  // Return the jqXHR object so we can chain callbacks
  return jQuery.ajax( options );
};

// Usage
$.cachedScript( "ajax/test.js" ).done(function( script, textStatus ) {
  console.log( textStatus );
});

Источник

Ответ 5

На самом деле существует лучший вариант, вы можете включить кеширование для определенных запросов, например:

$.ajaxPrefilter(function( options ) {
  if ( options.type==='GET' && options.dataType ==='script' ) {
      options.cache=true;
  }
});

Ответ 6

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

Я написал такую ​​функцию. Вы можете протестировать вкладку Сеть в инструментах Firebug или Chrome dev. Это однократно загружает один и тот же файл. Вам просто нужно скопировать в ваши файлы функцию getScriptOnce и глобальный массив ScriptArray

var getScriptOnce = (function(url, callback) {
  var scriptArray = []; //array of urls
  return function (url, callback) {
      //the array doesn't have such url
      if (scriptArray.indexOf(url) === -1){
          if (typeof callback === 'function') {
              return $.getScript(url, function(script, textStatus, jqXHR) {
                  scriptArray.push(url);
                  callback(script, textStatus, jqXHR);
              });
          } else {
              return $.getScript(url, function(){
                  scriptArray.push(url);
              });
          }
      }
      //the file is already there, it does nothing
      //to support as of jQuery 1.5 methods .done().fail()
      else{
          return {
              done: function () {
                  return {
                      fail: function () {}
                  };
              }
          };
      }
  }
}());

/*#####################################################################*/
/*#####################################################################*/


//TEST - tries to load the same jQuery file twice
var jQueryURL = "https://code.jquery.com/jquery-3.2.1.js";
console.log("Tries to load #1");
getScriptOnce(jQueryURL, function(){
  console.log("Loaded successfully #1")
});

//waits 2 seconds and tries to load again
window.setTimeout(function(){
  console.log("Tries to load #2");
  getScriptOnce(jQueryURL, function(){
    console.log("Loaded successfully #2");
  });
}, 2000);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>