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!
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.
Cela redirigera toujours vers /index.html
au cas où aucun fichier ne serait trouvé et qui déclencherait le routage de l'application.
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:
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
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.
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:
npm run build
)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.