web-dev-qa-db-fra.com

Comment faire que CloudFront ne cache jamais index.html sur le compartiment S3

J'ai une application React hébergée sur un seau S3. Le code est minifié avec yarn build (c'est une application basée sur create-react-app). Le dossier build ressemble à ceci:

build
├── asset-manifest.json
├── favicon.ico
├── images
│   ├── map-background.png
│   └── robot-icon.svg
├── index.html
├── js
│   ├── fontawesome.js
│   ├── packs
│   │   ├── brands.js
│   │   ├── light.js
│   │   ├── regular.js
│   │   └── solid.js
│   └── README.md
├── service-worker.js
└── static
    ├── css
    │   ├── main.bf27c1d9.css
    │   └── main.bf27c1d9.css.map
    └── js
        ├── main.8d11d7ab.js
        └── main.8d11d7ab.js.map

Je ne veux jamais que index.html soit mis en cache, car si je mets à jour le code (ce qui provoque la mise à jour du suffixe hexadécimal dans main.*.js), il faut que la prochaine visite de l'utilisateur récupère le changement <script src> dans index.html.

Dans CloudFront, je ne peux que sembler exclure les chemins, et exclure "/" ne semble pas fonctionner correctement. J'obtiens un comportement étrange lorsque je modifie le code, et si je clique sur Actualiser, je le vois, mais si je quitte Chrome et que je reviens en arrière, je vois du code très obsolète pour une raison quelconque.

Je ne veux pas avoir à déclencher une invalidation à chaque publication de code (via CodeBuild). Y a-t-il un autre moyen? Je pense que l’un des problèmes est que, comme il s’agit d’une application utilisant React Router, je dois faire quelques astuces en réglant le document d’erreur sur index.html et en forçant un statut HTTP 200 au lieu de 403.

27
ffxsam

Si vous ne voulez jamais que index.html soit mis en cache, définissez l'en-tête Cache-Control: max-age=0 sur ce fichier uniquement. CloudFront adressera une requête à votre compartiment Origin S3 à l’occasion de every request, mais il semblerait que ce comportement soit souhaité.

Si vous souhaitez définir des délais d'expiration plus longs et invalider manuellement le cache CloudFront, vous pouvez utiliser un * ou un /* comme chemin d'invalidation (et non le / comme vous l'avez mentionné). Cela peut toutefois prendre jusqu'à 15 minutes à tous les nœuds CloudFront Edge du monde pour refléter les modifications apportées à votre origine.

27
Luke Peterson

Voici la commande que j'ai exécutée pour définir le contrôle du cache sur mon fichier index.html après avoir chargé de nouveaux fichiers sur s3 et invalidé Cloudfront:

aws s3 cp s3://bucket/index.html s3://bucket/index.html --metadata-directive REPLACE --cache-control max-age=0
5
chadhamre

Une solution basée sur la configuration CloudFront:

Accédez à votre distribution CloudFront, sous l'onglet "Comportement" et créez un nouveau comportement . Spécifiez les valeurs suivantes:

  • Modèle de chemin: index.html
  • Mise en cache d'objets: personnaliser
  • TTL maximum: 0 (ou une autre très petite valeur)
  • TTL par défaut: 0 (ou une autre très petite valeur)

Enregistrez cette configuration.

CloudFront ne cache plus index.html.

0
seza443