J'ai mon site Web hébergé sur S3 avec CloudFront en tant que CDN, et j'ai besoin que ces deux URL se comportent de la même manière et servent le fichier index.html dans le répertoire:
example.com/directory
example.com/directory/
Celui avec le /
à la fin invite incorrectement le navigateur à télécharger un fichier de zéro octet avec un hachage aléatoire pour le nom du fichier. Sans la barre oblique, il renvoie ma page 404.
Comment puis-je obtenir les deux chemins pour livrer le fichier index.html dans le répertoire?
S'il y a un moyen, je suis "supposé" pour faire ça, super! C'est ce que j'espère, mais sinon j'essaierai probablement d'utiliser Lambda @ Edge pour faire une redirection. J'en ai besoin pour d'autres situations de toute façon, donc des instructions sur la façon de faire une redirection 301 ou 302 à partir de Lambda @ Edge seraient également utiles:)
Mise à jour (selon le commentaire de John Hanley)
curl -i https://www.example.com/directory/
HTTP/2 200 content-type: application/x-directory content-length: 0 date: Sat, 12 Jan 2019 22:07:47 GMT last-modified: Wed, 31 Jan 2018 00:44:16 GMT etag: "[id]" accept-ranges: bytes server: AmazonS3 x-cache: Miss from cloudfront via: 1.1 [id].cloudfront.net (CloudFront) x-amz-cf-id: [id]
Mettre à jour
CloudFront a un ensemble de comportements, transférer http vers https et envoyer les requêtes à S3. Il a également une route d'erreur 404 sous l'onglet Erreurs.
3 Réponses :
Ce type de comportement est généralement contrôlé / causé par vos données d'en-tête HTTP (s), en particulier, le Content-Type que votre client reçoit.
- Dans Chrome, accédez à une URL, cliquez avec le bouton droit de la souris, sélectionnez Inspecter pour ouvrir les outils de développement.
- Sélectionnez l'onglet Réseau.
- Rechargez la page, sélectionnez n'importe quelle requête HTTP dans le panneau de gauche et les en-têtes HTTP s'afficheront dans le panneau de droite.
Bien pensé! J'ai un script qui duplique tous mes fichiers html sans l'extension .html et les ajoute dans S3 avec le type de contenu défini sur HTML. Cela pourrait être une source de problèmes. Découvrons-le...
D'accord, n'a pas aidé: (
S3 propose uniquement des documents d'indexation automatique lorsque vous avez activé et que vous utilisez les fonctionnalités d'hébergement de site Web du compartiment, en pointant vers le point de terminaison d'hébergement de site Web du compartiment, $ {bucket} .s3-website. $ {region } .amazonaws.com
plutôt que le point de terminaison REST générique du bucket, $ {bucket} .s3.amazonaws.com
.
Les points de terminaison de site Web et les points de terminaison REST ont nombreuses différences , y compris celle-ci.
Le La raison pour laquelle vous voyez ces fichiers de 0 octet pour les clés d'objet se terminant par /
est que vous créez des objets de dossier dans le compartiment à l'aide de la console S3 ou d'un autre utilitaire qui crée en fait les objets de 0 octet. Ils ne sont pas nécessaires, une fois que les dossiers ont des objets "dans" eux - mais ils sont le seul moyen d'afficher un dossier vide dans la console S3, qui affiche un objet nommé foo /
comme un dossier nommé foo
, même s'il n'y a pas d'autres objets avec un préfixe de clé foo /
. Cela fait partie de l'émulation visuelle d'une hiérarchie de dossiers dans la console, même si les objets dans S3 ne sont jamais vraiment "dans" des dossiers.
Si, pour une raison quelconque, vous devez utiliser le point de terminaison REST - comme vous ne voulez pas rendre le bucket public - alors vous avez besoin de deux déclencheurs Lambda @ Edge dans CloudFront, pour émuler cette fonctionnalité assez étroitement.
Un déclencheur Origin Request peut inspecter et modifier les demandes après la vérification du cache CloudFront, avant que la demande ne soit envoyée à l'origine. Nous utilisons ceci pour rechercher un chemin se terminant par /
et ajouter index.html
si nous trouvons cela.
Une Réponse d'origine em> trigger peut inspecter et éventuellement modifier les réponses, avant qu'elles ne soient écrites dans le cache CloudFront. Le déclencheur Origin Response peut également inspecter la demande d'origine qui a précédé la demande qui a généré la réponse. Nous utilisons ceci pour vérifier si la réponse est une erreur. Si tel est le cas et que la demande d'origine ne semble pas concerner un document d'index ou un fichier (en particulier, après la dernière barre oblique du chemin, un "fichier" comporte au moins un caractère, suivi de un point, suivi d'au moins un caractère supplémentaire - et si c'est le cas, c'est probablement un "fichier"). Si ce n'est ni l'une ni l'autre de ces choses, nous redirigeons vers le chemin d'origine plus un /
final que nous ajoutons.
Les déclencheurs Origin Request et Origin Response se déclenchent uniquement en cas d'échec du cache. Lorsqu'il y a un hit de cache, aucun des déclencheurs ne se déclenche, car ils se trouvent du côté d'origine de CloudFront - l'arrière du cache. Les requêtes qui peuvent être servies à partir du cache sont servies à partir du cache, donc les déclencheurs ne sont pas appelés.
Ce qui suit est une fonction Lambda @ Edge écrite dans Node.js 8.10. Cette fonction Lambda modifie son comportement afin qu'elle se comporte comme une demande d'origine ou une réponse d'origine, en fonction du contexte. Après avoir publié une version dans Lambda, associez l'ARN de cette version aux paramètres CloudFront Cache Behavior en tant que à la fois une demande d'origine et un déclencheur de réponse d'origine.
'use strict'; // combination origin-request, origin-response trigger to emulate the S3 // website hosting index document functionality, while using the REST // endpoint for the bucket // https://stackoverflow.com/a/54263794/1695906 const INDEX_DOCUMENT = 'index.html'; // do not prepend a slash to this value const HTTP_REDIRECT_CODE = '302'; // or use 301 or another code if desired const HTTP_REDIRECT_MESSAGE = 'Found'; exports.handler = (event, context, callback) => { const cf = event.Records[0].cf; if(cf.config.eventType === 'origin-request') { // if path ends with '/' then append INDEX_DOCUMENT before sending to S3 if(cf.request.uri.endsWith('/')) { cf.request.uri = cf.request.uri + INDEX_DOCUMENT; } // return control to CloudFront, to send request to S3, whether or not // we modified it; if we did, the modified URI will be requested. return callback(null, cf.request); } else if(cf.config.eventType === 'origin-response') { // is the response 403 or 404? If not, we will return it unchanged. if(cf.response.status.match(/^40[34]$/)) { // it's an error. // we're handling a response, but Lambda@Edge can still see the attributes of the request that generated this response; so, we // check whether this is a page that should be redirected with a trailing slash appended. If it doesn't look like an index // document request, already, and it doesn't end in a slash, and doesn't look like a filename with an extension... we'll try that. // This is essentially what the S3 web site endpoint does if you hit a nonexistent key, so that the browser requests // the index with the correct relative path, except that S3 checks whether it will actually work. We are using heuristics, // rather than checking the bucket, but checking is an alternative. if(!cf.request.uri.endsWith('/' + INDEX_DOCUMENT) && // not a failed request for an index document !cf.request.uri.endsWith('/') && // unlikely, unless this code is modified to pass other things through on the request side !cf.request.uri.match(/[^\/]+\.[^\/]+$/)) // doesn't look like a filename with an extension { // add the original error to the response headers, for reference/troubleshooting cf.response.headers['x-redirect-reason'] = [{ key: 'X-Redirect-Reason', value: cf.response.status + ' ' + cf.response.statusDescription }]; // set the redirect code cf.response.status = HTTP_REDIRECT_CODE; cf.response.statusDescription = HTTP_REDIRECT_MESSAGE; // set the Location header with the modified URI // just append the '/', not the "index.html" -- the next request will trigger // this function again, and it will be added without appearing in the // browser's address bar. cf.response.headers['location'] = [{ key: 'Location', value: cf.request.uri + '/' }]; // not strictly necessary, since browsers don't display it, but remove the response body with the S3 error XML in it cf.response.body = ''; } } // return control to CloudFront, with either the original response, or // the modified response, if we modified it. return callback(null, cf.response); } else // this is not intended as a viewer-side trigger. Throw an exception, visible only in the Lambda CloudWatch logs and a 502 to the browser. { return callback(`Lambda function is incorrectly configured; triggered on '${cf.config.eventType}' but expected 'origin-request' or 'origin-response'`); } };
p >
C'est en profondeur, merci beaucoup !!! Je crains de rendre le seau public, mais je suppose que je n'ai pas à l'être. J'ai également hâte que CloudFront devienne un CDN Web. J'ai d'autres besoins comme un routage plus avancé (example.com/users/username, où le nom d'utilisateur est passé en tant que variable ... et cetera). Je pense que je vais essayer votre fonction Lambda @ Edge, merci beaucoup !!!
Cela marche. J'ai également testé avec une distribution CloudFront qui utilise une fonction Lambda pour l'authentification et cela fonctionne. Avant fixation, pour un sous-dossier de site Web / test-folder /
. Microsoft Edge crée des fichiers Téléchargements vides nommés dossier-test *
et Chrome crée des fichiers vides nommés téléchargement *
. Cette réponse a résolu ce problème.
Les réponses données sont fausses. Cloudfront a sa propre configuration pour que www.yourdomain.com/ serve un document. Il s'appelle «objet racine par défaut» et sa configuration se trouve sous l'onglet «général» de votre distribution cloudfront. Voici les étapes complètes pour obtenir un domaine personnalisé compatible SSL / https + cloudfront + s3.
C'est une meilleure solution car elle évite de donner un accès public à un compartiment S3.
L'onglet Général n'existe plus. Recherchez dans la page "Objet racine par défaut"
La façon dont vous vous attendez (avec / à la fin return index.html) est la façon dont les sites Web S3 fonctionnent (devraient fonctionner). Avec la barre oblique, vous devriez voir une redirection 302. Utilisez
curl -i http://example.com/directory/
et mettez à jour votre question avec la réponse. Référence AWS S3: docs.aws.amazon.com/AmazonS3/latest/ dev /…Je suppose que CloudFront aurait dû être mentionné dès le départ.
Dans CloudFront, utilisez-vous le point de terminaison du site Web (console S3 -> propriétés -> hébergement de site Web statique -> point de terminaison)? Vous devrez utiliser le point de terminaison sans la partie
http: //
.example.com.s3.amazonaws.com
docs.aws.amazon.com/AmazonS3/latest/dev/...@JohnHanley Yup, c'est l'URL dans mon onglet origines. L'hébergement de site Web dans S3 n'est cependant pas activé pour ce compartiment.
Dans CloudFront, quelle est la valeur de
Default Root Object
?Voici un exemple de code pour Lambda @Edge pour les redirections: docs.aws .amazon.com / AmazonCloudFront / latest / DeveloperGuide /…
Réponse StackOverflow avec exemple de code pour Lambda @Edge pour la gestion de
index.html
: stackoverflow.com/a/50458087/ 8016720"Sans la barre oblique, nous obtenons le comportement correct, qui est de servir le fichier index.html dans ce répertoire." et "L'hébergement de site Web dans S3 n'est cependant pas activé pour ce compartiment. " ne peut pas être tous les deux vrais. La fonction d'hébergement de site Web S3 est requise pour que les documents d'index soient utilisés par S3 et dans le cadre du processus, S3 redirige d'abord le navigateur de
/ foo
vers/ foo /
(comme tous les serveurs Web le font ou devraient le faire) avant d'afficher le objet àfoo / index.html
afin que les chemins relatifs dans le HTML soient corrects.J'ai complètement oublié votre commentaire
L'hébergement de site Web dans S3 n'est cependant pas activé
. Ceci est nécessaire pour que la redirection se produise.@JohnHanley J'ai activé l'hébergement de site Web S3, mais le site Web se comporte de la même manière. l'objet racine par défaut est index.html
@Costa après avoir activé la fonctionnalité d'hébergement de site Web dans S3, vous devez également définir le nom de domaine d'origine dans CloudFront sur
$ {bucketname} .s3-website. $ {Bucketregion} .amazonaws.com
. Avec$ {bucketname} .s3.amazonaws.com
, cela ne fonctionnera pas.Oui, et si vous faites cela, vous devez également ouvrir le seau S3 au monde, ce qui pourrait être bien.
C'est la seule option native . La gestion des documents d'index est une fonctionnalité de la fonctionnalité d'hébergement de site Web , ce qui nécessite également que les objets soient lisibles publiquement. Sinon, vous auriez besoin des fonctions de déclenchement Lambda @ Edge pour réécrire certaines requêtes avant qu'elles ne passent à S3 et réécrire les erreurs 403/404 sur les chemins sans la barre oblique de fin, pour les rediriger.