web-dev-qa-db-fra.com

Vue.js Router: mode historique et AWS S3 (RoutingRules)

J'ai une application Vue.js opérationnelle avec Amazon S3 et Cloudflare.

Lorsque j'ouvre l'index et que je navigue vers/tableau de bord, tout fonctionne bien. Mais lorsque j'ouvre un itinéraire comme le tableau de bord directement dans un nouvel onglet ou que je rafraîchis la page, je reçois l'erreur suivante de S3:

404 Not Found

Code: NoSuchKey
Message: The specified key does not exist.
Key: unternehmen
RequestId: 6514F8A1F4C29235
HostId: +BVrPLJSGdzSYogzWZ4GMBXkgkdSJWRVJVhcSs4EI/lmMUR422aCtCxpBGU6AMe5VkS1UbEn/Lc=

Il suffit de lire que le problème est le mode historique de Vue.js: https://router.vuejs.org/de/essentials/history-mode.html

Je voudrais résoudre le problème avec une règle de routage dans mon compartiment Amazon S3. À quoi ressemblerait Apache RewriteRule pour S3?

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteBase /
  RewriteRule ^index\.html$ - [L]
  RewriteCond %{REQUEST_FILENAME} !-f
  RewriteCond %{REQUEST_FILENAME} !-d
  RewriteRule . /index.html [L]
</IfModule>

J'ai essayé ce qui suit mais cela ne fonctionne pas:

<RoutingRules>
  <RoutingRule>
    <Condition>
      <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
    </Condition>
    <Redirect>
      <HostName>domain.com</HostName>
      <ReplaceKeyWith>index.html</ReplaceKeyWith>
    </Redirect>
  </RoutingRule>
</RoutingRules>

Si je le fais comme ça, je reçois juste mon en-tête et mon pied de page, mais rien de plus.

Je vous remercie!

17
mrks

Je sais que cette réponse arrive tard mais si quelqu'un d'autre cherche un autre moyen de résoudre ce problème dans cloudfront, il n'est pas nécessaire de créer des pages personnalisées sur s3 en redirigeant les utilisateurs lorsque les pages ne sont pas trouvées. Au lieu de le faire, des réponses d'erreur personnalisées peuvent être créées dans cloudfront pour la distribution.

Custom errors

Cela redirigera toujours vers /index.html au cas où aucun fichier ne serait trouvé et qui déclencherait le routage de l'application.

38
Mindastic

J'héberge un PWA statique fait en Vue sur S3 en utilisant "l'hébergement de site Web statique" et cela fonctionne comme prévu. Ce que j'ai fait était assez simple - j'ai ajouté ceci:

<RoutingRules>
  <RoutingRule>
    <Condition>
      <HttpErrorCodeReturnedEquals>403</HttpErrorCodeReturnedEquals>
    </Condition>
    <Redirect>
      <ReplaceKeyWith></ReplaceKeyWith>
    </Redirect>
  </RoutingRule>
</RoutingRules>

Aux propriétés du compartiment S3. Voir l'image ci-dessous: S3 Properties

Pour mon compartiment S3, chaque fois que vous essayez d'accéder à un fichier qui n'existe pas, vous recevrez un 403 (interdit) au lieu d'un 404. C'est pourquoi j'ai changé le HttpErrorCodeReturnedEquals en 403. J'ai également remplacé le ReplaceKeyWith par une chaîne vide comme "index.html" comme ne déclenchant pas l'itinéraire correct.

J'espère que ça aide.

À la vôtre, Alex

4
Alexandre Andrade

Je pense que ce problème a deux composantes:

1.

Si une demande est faite directement (en dehors de l'application Javascript) vers un sous-chemin tel que/jobs, alors S3 renvoie un 404, car le chemin/objet n'existe pas. Le moyen le plus simple de résoudre ce problème est depuis S3 lui-même, où vous redirigez toutes les pages d'erreur vers index.html.

Cependant, cela ne fonctionne pas à partir d'un CDN tel que Cloudfront, et probablement Cloudflare.

Une bonne astuce consiste à utiliser des fichiers à l'intérieur de S3 qui redirigent les utilisateurs comme ceci:

jobs/-> /index.html jobs -> /index.html

Par exemple, si quelqu'un fait une demande au site/il obtiendra le fichier html suivant:

"redirect":"<html><head><meta http-equiv=\"refresh\" content=\"0; url=http://example.com/site/index.html\" /></head>
<body>Redirecting to <a href=\"http://example.com/site/index.html\">Home</a></body></html>"

Deuxièmement...

Si je le fais comme ça, je reçois juste mon en-tête et mon pied de page, mais rien de plus.

C'est un problème que j'ai eu lorsque la vue de routeur ne s'initialise pas correctement, même si le composant qui contient la vue de routeur a été chargé.

Ce que j'ai fait pour l'instant, c'est rediriger mon routeur lorsque le composant principal "App" est créé:

created () {
console.log('route', this.$route.path)
this.$router.replace(this.$route.query.redirect || '/')
}

Cela a l'avantage supplémentaire de supprimer le fichier index.html de votre chemin (qui a été ajouté par vos nouvelles redirections) tout en forçant votre vue de routeur à s'afficher ...

Mon composant #app est le composant parent, avec une barre de navigation, un pied de page et la vue de routeur qui rend toutes les sous-pages/composants.

2
comfytoday

Une façon de faire fonctionner cela avec le routage en mode historique et sans utiliser CloudFront est de créer les fichiers vers lesquels vos URI pointeraient. Supposons donc que vous utilisiez index.html comme point d'entrée et que vous n'ayez qu'une seule autre page à laquelle vous donnez le chemin page2.html.

Ensuite, vous devez adapter votre processus de génération et de déploiement pour effectuer les opérations suivantes:

  1. Intégrez votre source dans une distribution de production (par exemple en utilisant npm run build)
  2. Assurez-vous que pour vos liens de routeur, vous créez un fichier par chemin d'accès qui est une copie du fichier d'origine. Dans le cas de l'exemple que je mentionne, il s'agirait de créer une copie de 'dist/index.html' vers 'dist/page2.html'
  3. Copiez le contenu du dossier dist dans votre compartiment S3

Notez que l'ordre des étapes 1 et 2 est important. Cela peut être facilement fait dans un script qui publie votre site Web. Je viens d'utiliser cette approche avec le résultat que je voulais; permettant d'actualiser une page et d'ouvrir des liens dans un nouvel onglet.

Les inconvénients que je vois sont les suivants: - surcharge de stockage des copies des fichiers - devez vous assurer que si vous ajoutez une page, n'oubliez pas de mettre à jour vos scripts de construction et de déploiement.

0
user35800

Si vous utilisez un hébergement statique sur AWS S3 et qu'il s'agit de l'application SPA (React, Vue, Angular etc), vous devez définir index.html comme page d'erreur: enter image description here