En configurant une politique de mise en cache HTTP pour votre serveur Nginx, vous pouvez indiquer aux navigateurs et aux proxies intermédiaires, tels qu'un CDN, de mettre en cache les ressources statiques comme les images, les fichiers CSS et JS. Pendant leur période de validité, les ressources mises en cache sont chargées directement depuis une copie locale, ce qui élimine la nécessité d'une requête vers le serveur. Cela améliore la vitesse de chargement du site web, réduit la bande passante du serveur et diminue la charge du serveur.
Exemples courants de politiques de mise en cache
Cette section présente des configurations de mise en cache courantes que vous pouvez appliquer directement à votre fichier de configuration Nginx. Tous les exemples utilisent la directive add_header ... always; pour ajouter un en-tête de mise en cache à toutes les réponses, y compris celles avec un code d'état de réponse 304 Not Modified.
Cas d'utilisation 1 : Mise en cache à long terme pour les ressources statiques
# Configure long-term caching for static assets
# - For filenames with a content hash (e.g., main.a1b2c3d4.js), a 1-year cache with 'immutable' is recommended.
location ~* "\.[a-f0-9]{8,}\.(css|js|png|jpg|jpeg|gif|svg|webp|ico|woff|woff2)$" {
# For assets with a hash generated by build tools: cache for 1 year, and instruct the browser to never revalidate.
add_header Cache-Control "public, max-age=31536003, immutable" always;
access_log off;
}
# - For filenames that are fixed and rarely change (e.g., logo.png), use a 30-day cache.
location ~* \.(css|js|png|jpg|jpeg|gif|svg|webp|ico|woff|woff2)$ {
# For generic static assets without a hash: cache for 30 days and allow both CDN and browser caching.
add_header Cache-Control "public, max-age=2592000" always;
access_log off;
}
Cas d'utilisation 2 : Mise en cache pour HTML et SPA
Les pages HTML, en particulier le fichier d'entrée d'une application monopage (SPA) comme index.html, sont fréquemment mises à jour à chaque nouveau déploiement. Par conséquent, évitez la mise en cache à long terme pour ces fichiers. Pour des raisons de performance, vous pouvez autoriser les navigateurs à mettre en cache ces fichiers, mais vous devez exiger qu'ils soient revalidés auprès du serveur avant chaque utilisation.
# For directly requested HTML files
location ~* \.html$ {
# Allows browser caching but requires revalidation with the server before each use.
# The 'private' directive prevents an intermediate proxy (like a CDN) from caching this response.
# The server must provide an ETag or Last-Modified header to support validation.
add_header Cache-Control "private, no-cache, must-revalidate" always;
}
Cette politique exige que le serveur renvoie un en-tête
ETagouLast-Modified, ce qui permet au navigateur d'effectuer une requête conditionnelle. Nginx fournit ces en-têtes pour les fichiers statiques par défaut, donc aucune configuration supplémentaire n'est nécessaire.Pour empêcher les proxies intermédiaires, tels que les CDN, de mettre en cache le contenu HTML, utilisez la directive « private ». Cela garantit que seul le navigateur de l'utilisateur final met en cache la réponse.
Cas d'utilisation 3 : Aucune mise en cache pour le contenu dynamique et sensible
Pour le contenu généré dynamiquement ou sensible, tel qu'un endpoint API, une page de profil utilisateur ou une page de paiement, empêchez les navigateurs et les proxies intermédiaires (comme les CDN ou les caches partagés) de stocker la réponse. Cela prévient les fuites de données et les incohérences.
# Example: For dynamic PHP scripts (adjust the path based on your setup)
location ~ \.php$ {
# ... other PHP-FPM configurations ...
# Disable all caching: Browsers, proxies, and CDNs must not store the response.
# 'no-store' is the strictest cache control directive.
add_header Cache-Control "no-store" always;
}
Configuration du cache client
Vous pouvez contrôler la mise en cache du navigateur en ajoutant les en-têtes Cache-Control et Expires aux réponses HTTP.
Directives principales
-
Directive
expires: Définit à la fois l'en-têteExpireset la valeurmax-agede l'en-têteCache-Control.Syntaxe :
expires [time|epoch|max|off];Exemple :
expires 30d;(met en cache la ressource pendant 30 jours),expires -1;(force le client à valider la ressource auprès du serveur avant utilisation (équivalent àCache-Control: no-cache), mais permet la mise en cache de la ressource).Remarque : La directive
add_headerest recommandée car elle offre un contrôle plus granulaire.
-
Directive
add_header: Ajoute un en-tête HTTP spécifié à la réponse.Syntaxe :
add_header <name> <value> [always];Description du paramètre
always- Par défaut,add_headers'applique uniquement aux réponses 2xx et 3xx. - Pour les réponses304 Not Modified, Nginx n'ajoute pas automatiquement les en-têtes personnalisés. Bien que les navigateurs réutilisent la politique de mise en cache de la réponse 200 initiale, vous devez ajouter le paramètrealwaysaux en-têtes de contrôle de cache pour plus de clarté et de compatibilité. Cela garantit que les en-têtes s'appliquent à tous les codes d'état de réponse.
Directives Cache-Control
public: La réponse peut être stockée par n'importe quel cache, y compris les navigateurs, les CDN et les serveurs proxy.private: La réponse ne peut être stockée que par le navigateur de l'utilisateur final, et non par des caches partagés comme les CDN. Ceci est utile pour le contenu contenant des informations spécifiques à l'utilisateur.no-cache: Exige que le client envoie une requête au serveur pour valider une copie mise en cache avant chaque utilisation. Si la ressource n'a pas changé, le serveur renvoie304 Not Modified, permettant au client d'utiliser le cache local et d'économiser de la bande passante.no-store: Interdit aux navigateurs et aux serveurs proxy de stocker toute partie de la réponse. Ceci convient aux données hautement sensibles.max-age=<seconds>: Définit la durée de vie (TTL) du cache en secondes.immutable: Informe le navigateur que le contenu de la ressource ne changera pas tant qu'il est mis en cache. C'est idéal pour les fichiers qui incluent un hachage de contenu dans le nom de fichier.
Déploiement et vérification
Modifiez la configuration. Ajoutez le bloc
locationau blocserverde votre site. Le fichier de configuration se trouve généralement dans/etc/nginx/conf.d/ou/etc/nginx/sites-enabled/.-
Rechargez la configuration
sudo nginx -t && sudo nginx -s reload -
Vérifiez l'en-tête de réponse. Utilisez
curlpour vérifier la présence de l'en-tête de cache. Cette méthode contourne tout cache du navigateur.curl -I http://your-domain.com/path/to/file.jsIl doit inclure les en-têtes attendus tels que
Cache-Control: public, max-age=31536000. -
Vérifiez le comportement
304(pour les politiques basées surno-cacheouETag) Testez avec un en-tête de validation :ETAG=$(curl -I http://example.com/file.js 2>/dev/null | grep -i etag | cut -d' ' -f2 | tr -d '\r') curl -H "If-None-Match: $ETAG" -I http://example.com/file.js # Expects a 304 response -
Vérifiez dans un navigateur
Ouvrez les outils de développement et accédez au panneau Réseau.
Sélectionnez la case à cocher Disable cache pour afficher le chargement initial. L'état doit être
200 OK.-
Désélectionnez la case et actualisez la page :
Aucune requête n'est effectuée ou affichée
(from cache)→ hit de cache fortRenvoie
304→ hit de cache conditionnel
FAQ
Les modifications ne prennent pas effet
Cause :
La commande
sudo nginx -s reloadn'a pas été exécutée.Un navigateur, un CDN ou un serveur proxy sert une réponse obsolète.
Priorité incorrecte de correspondance du bloc
location.
Solution :
Utilisez
curl -I http://your-urlpour vérifier l'en-tête de réponse directement depuis le serveur.Vérifiez l'ordre des blocs
location. Les correspondances d'expressions régulières (comme~* \.(css|js)$) ont priorité sur les correspondances de préfixe (comme/static/). Une requête peut être traitée par la mauvaise règle en raison de cette priorité.
Contenu dynamique mis en cache incorrectement
Cause : L'expression régulière pour les ressources statiques est trop large (par exemple, ~* \.js$ correspond à /api/user.js).
Solution :
Restreignez le chemin :
location ~* ^/static/.*\.(css|js)$Assurez-vous que le
locationpour les interfaces dynamiques telles que/api/et\.php$est prioritaire ou explicitement exclu de la mise en cache.
Politiques de mise en cache conflictuelles
Cause : Plusieurs blocs
locationcorrespondent à la même requête, mais seul le premier prend effet.-
Solution : Utilisez un bloc
mappour consolider les politiques et définir dynamiquement la politique de mise en cache en fonction du type de contenu.# In the http block map $sent_http_content_type $cache_control { ~^image/ "public, max-age=2592000"; text/css "public, max-age=2592000"; application/javascript "public, max-age=2592000"; default "no-cache"; } # In the server block add_header Cache-Control $cache_control always;