web-dev-qa-db-fra.com

Jquery getScript mise en cache

Par défaut, $ .getScript () désactive la mise en cache et vous pouvez utiliser $ .ajaxSetup et définir la mise en cache sur true. Lorsque vous vérifiez si le script est réellement mis en cache avec Firebug, la plupart du temps, il revient à 200 (ce qui signifie que le script est une nouvelle copie) et une sur 20 ou 30 fois, il reviendra 304 version). Pourquoi reçoit-il une nouvelle copie la grande majorité du temps?

$.ajaxSetup({
    cache: true
 });

 $.getScript( scriptFile );

Les fichiers récupérés par getScript n'ont pas été modifiés et les demandes constituent un changement de page distinct.

27
Case

Il y a une erreur à la date à laquelle cette question a été postée dans laquelle Firefox et Chrome déclaraient qu'un script n'est pas chargé à partir du cache alors qu'il l'est. A la date de cette réponse, ce problème existe toujours. Le moyen le plus simple de tester consiste à utiliser console.log et à envoyer un numéro de version. 

Pour mettre en cache un script chargé dynamiquement, il suffit de le code suivant.

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

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

Pour le développement, vous devriez commenter cache: true.

8
Case

Tout d’abord, clarifions ce que cela signifie signifie que jQuery désactive la mise en cache.

Lorsque jQuery désactive le cache, cela signifie que force le fichier à être chargé de nouveau par le navigateur avec une astuce, par exemple en ajoutant un nombre aléatoire supplémentaire en tant que paramètre à la fin de l'URL.

Lorsque jQuery active le cache, ne force rien et laisse le cache que vous avez défini dans l'en-tête de ce fichier. Ce qui signifie que si vous n'avez pas défini sur l'en-tête des paramètres de fichiers pour le conserver dans le cache du navigateur, le navigateur essaiera de le charger à nouveau par certaines méthodes.

Donc, pour activer le cache par jQuery, vous devez également définir les en-têtes de cache corrects sur vos fichiers statiques afin de les conserver dans le cache du navigateur. Sinon, le navigateur peut essayer de les charger à nouveau.

Pour les fichiers que le navigateur voit la date de création sur l’en-tête, puis se connecte au serveur en demandant à nouveau l’en-tête, le compare et, s’il n’a pas eu de modification, ne le charge pas à nouveau, mais appelle le serveur.

Pour les fichiers que vous avez définis et que vous ne demandez pas au serveur avant cette date, le navigateur le charge directement à partir du cache s’il le trouve.

Résumer:
Le cache:true est laissé au navigateur décider du cache de ce fichier à partir de l’en-tête que vous envoyez.
Le cache:false force le chargement du fichier.

Quelques questions relatives aux questions de cache:
mise en cache de fichiers JavaScript
IIS7 Cache-Control

Le code intérieur
La getScript() appelle la jQuery.get() qui est une fonction abrégée Ajax de

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

Donc, en appelant la getScript(), vous effectuez un appel ajax, et jQuery ne conserve aucun type de cache de vos fichiers si c'est ce que vous pensez en premier lieu.

Fonction personnalisée pour charger les sripts
Si vous n'avez pas réussi à créer un cache global: true et que vous ne devez charger que certains fichiers avec le cache: true, vous pouvez créer une fonction personnalisée comme suit: 

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

Cela n'est pas affecté par le paramètre de cache global et charge les fichiers de script sans rien ajouter de paramètre non cache à la fin.

24
Aristos

Par défaut, $ .getScript () définit le paramètre de cache sur false. Cela ajoute un paramètre de requête horodaté à l'URL de la demande pour garantir que le navigateur télécharge le script chaque fois qu'il est demandé.

le site doc de jQuery a une extension Nice pour ne pas ajouter d'horodatage à la requête et ignorer le cache:

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

La source

2
gdoron

Il existe une meilleure option, vous pouvez activer la mise en cache pour certaines demandes, par exemple:

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

Je sais que ceci est un ancien post, et la réponse existante est la vraie réponse, mais en ce qui concerne la préoccupation d’Iscariot, CELA EST VRAIMENT IS CACHING (au moins en quelque sorte, en quelque sorte). Ceci est juste une bizarrerie de Firefox. Peut-être que cela s’avérera utile à d’autres qui sont troublés par cette bizarrerie.

J'ai testé ce concept avec un fichier javascript TRÈS GRAND qui définit les polygones de carte Google pour les limites des districts Idot DOT en fonction de tableaux de dizaines de milliers de latlons (la taille du fichier non compressé est de 2 806 257, mais je l'exécute via un processus de compression). Utilisation du javascript suivant

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

et vous pouvez voir le php correspondant (vous ne voulez pas du fichier Districts.js, cela prendrait trop de place sur ce post, alors voici 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's 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;
}
?>

Il est important de noter qu'appeler les fonctions d'en-tête de php AVANT que le script exécute même la chaîne que vous allez imprimer est différent de chrome et peut-être (probablement, je suis trop paresseux pour vérifier) ​​que d'autres navigateurs firefox apparaissent pour faire un ping au serveur vérifiez les en-têtes avant d'utiliser le cache. Peut-être qu'avec davantage de recherches, vous pourriez déterminer si cela concerne autant les éléments que l'ajax (probablement pas).

J'ai donc effectué cinq tests montrant les temps de chargement de ce script avec ajax, comme indiqué dans firebug. Voici les résultats

#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

Comme vous pouvez le constater, la connexion de mon serveur localhost à un client Web n’est pas la plus cohérente et les spécifications de mon ordinateur portable sont un peu minables (processeur à cœur unique et tout, il date également de quelques années) MAIS LE POINT est un significatif baisse du temps de chargement après le chargement du cache.

[Aussi, si quelqu'un est curieux sans le script de compression (ce n'est pas comme si les tabulations, les espaces ou les nouvelles lignes sont gâchés, il doit toujours être lisible) - le chargement prend entre 7 et 8 secondes, mais je ne ferai pas cela cinq fois. fois]

Donc, ne craignez rien, c'est vraiment la mise en cache. Pour les scripts plus petits qui ne prennent que ms à charger, vous ne remarquerez peut-être pas la différence dans firefox, honnêtement; tout simplement parce qu'il vérifie les en-têtes du serveur. Je le sais à cause du temps de chargement qui a changé depuis le déplacement de ces fonctions d'en-tête de la fin du script au début. Si vous avez ces fonctions après que php ait traversé la chaîne, le chargement est plus long.

J'espère que cela t'aides!

2
Assimilater

Vous recherchez peut-être une fonction getScriptOnce qui, si elle sait que le fichier a déjà été chargé avec succès, ne le charge pas à nouveau lorsque cette fonction est appelée. 

J'ai écrit une telle fonction. Vous pouvez tester avec l’onglet Réseau dans les outils de développement de Firebug ou de Chrome. Cela charge simplement le même fichier une fois. Il vous suffit de copier dans vos fichiers la fonction getScriptOnce et le tableau global 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>

0