web-dev-qa-db-fra.com

Empêcher le navigateur de mettre en cache un fichier texte

J'ai une application Web qui s'exécute sur un serveur Apache sur l'intranet d'une organisation. Dans cette application Web, une fonction JavaScript charge un fichier texte spécifique via JavaScript.

xhttp = new XMLHttpRequest();
var data = xhttp.open("GET", "data.txt", false);

Pendant l'utilisation de l'application Web, ce fichier texte peut changer de contenu. Ces modifications doivent être reflétées dans l'application Web, c'est-à-dire que le fichier texte doit être rechargé et ne pas être lu à partir du cache du navigateur. Cependant, le navigateur (en particulier Chromium) met en cache le fichier texte. Qu'est-ce qui peut être fait pour que le navigateur demande toujours le fichier texte au serveur et ne le cache jamais?

Ce rechargement peut-il toujours se faire uniquement avec HTML/JavaScript (ou Perl)?

Je n'ai pas accès à la configuration du serveur Apache. L'application utilise beaucoup de scripts Perl pour assembler la page Web que je ne connais pas mais à laquelle j'ai accès.

4
nutgoodinuff

Vous avez deux approches à ce problème.

La méthode propre consiste à définir les en-têtes renvoyés pour GET data.txt afin d'empêcher le navigateur (ou le proxy) de stocker la réponse en cache. En utilisant Apache, cela peut généralement être fait en ajoutant quelques lignes dans un fichier .htaccess. Si ce fichier data.txt est un fichier statique, c'est le seul moyen de contrôler les en-têtes. De https://stackoverflow.com/questions/11532636/prevent-http-file-caching-in-Apache-httpd-mamp

<filesMatch "data\.txt$">
  FileETag None
  <ifModule mod_headers.c>
     Header unset ETag
     Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
     Header set Pragma "no-cache"
     Header set Expires "Wed, 11 Jan 1984 05:00:00 GMT"
  </ifModule>
</filesMatch>

Si GET data.txt est géré par un script (Perl, php, Java, etc.), la définition de cet en-tête peut être effectuée à partir du script lui-même (elle doit être exécutée avant l'envoi du contenu). Voici un exemple en php

<?php
header("Cache-Control: max-age=0, no-cache, no-store, must-revalidate"); // HTTP/1.1
header("Expires: Wed, 11 Jan 1984 05:00:00 GMT"); // Date in the past
?>

Vous trouverez un exemple Perl ici https://stackoverflow.com/questions/18056127/set-http-header-in-Perl-to-force-download-the-content

Si aucun de ces applie, vient ici ...

Le moyen rapide et sale.

Si vous ne pouvez pas empêcher la mise en cache de l'appel, vous devez simplement modifier l'appel et "piéger" le cache. GET data.txt? Tout-différent-ici-va-faire-le-travail.just-doit-être-différent-chaque-fois

Une méthode courante consiste à utiliser un nombre aléatoire, à utiliser l'heure actuelle en millisecondes ou une combinaison des deux.

var ms = Date.now();
var xhttp = new XMLHttpRequest();
var data = xhttp.open("GET", "data.txt?dummy="+ms, false);
9
Antony Gibbs

La bonne façon serait de changer la configuration Apache (via htaccess ou un fichier de configuration) avec les en-têtes d'expiration avec un temps de mise en cache très bas. Vérifiez si vous avez accès au fichier .htaccess s'il ne s'agit pas d'un fichier de configuration Apache.

Cependant, si vous ne pouvez absolument pas modifier .htaccess ou Apache conf, il peut y avoir un truc pour y arriver. La plupart des développeurs utilisent cette astuce pour renouveler le cache du navigateur chaque fois qu'ils modifient des fichiers qui sont mis en cache plus longtemps dans le cache du navigateur, mais cette astuce peut également être utilisée dans votre cas.

L'astuce consiste à ajouter une version au nom du fichier. par exemple. data.txt?v=1 pour vider le cache du navigateur. Dans votre cas, vous pouvez utiliser un numéro aléatoire comme numéro de version pour que le navigateur renouvelle le fichier à chaque appel. Cependant, si le nombre aléatoire est répété, l'utilisateur verra à nouveau un ancien fichier. Vous pouvez utiliser Math.random(); pour la génération de nombres aléatoires dans JS.

var data = xhttp.open("GET", "data.txt?v=0.2544544383", false);

Attention: Ce n'est qu'une astuce et non la bonne façon. Cela réduit simplement la probabilité de recharger le fichier mis en cache à un très petit nombre mais ne garantit pas que le fichier de cache ne sera pas récupéré.

Vous devez vérifier quelle est la période de mise en cache des fichiers .txt dans le navigateur. Si elle est très grande (par exemple 1 mois), vous ne devriez pas utiliser cette technique mais si elle est beaucoup plus basse (par exemple 1 heure), vous pouvez utiliser cette technique car la probabilité qu'un même nombre aléatoire généré pour le même utilisateur augmente inférieur.

2
Aakash