web-dev-qa-db-fra.com

Rediriger vers index.html pour le sous-dossier S3

J'ai un nom de domaine example.com. J'ai un seau S3 nommé example.com setup avec un fichier index.html qui fonctionne. Maintenant, j'aime créer deux sous-dossiers appelés old et new, chacun contenant une version distincte d'une application à une seule page. Demander https://example.com/old (j'aime omettre le index.html lors de la saisie de la demande dans la barre d'adresse du navigateur) ouvre le fichier index.html du sous-dossier old et demander https://example.com/new ouvrirait le index.html. Quelle est la meilleure façon de faire ces redirections? Dois-je configurer quelque chose dans Route 53 example.com/old -> example.com/old/index.html ou y a-t-il une meilleure façon de le faire?

8
g3blv

Pas besoin d'une fonction lambda pour ajouter du coût et de la complexité à votre projet.

La réponse suivante est citée de https://stevepapa.com/

https://stevepapa.com/my-great-new-post/ devrait fonctionner de la même manière que: https://stevepapa.com/my-great-new-post/index.html

Il existe un petit moyen astucieux de les transférer dans la distribution Cloudfront, et cela implique de changer la source Origin de celle que Cloudfront vous présente par défaut.

Lors de la sélection de la source d'origine, Cloudfront affiche une liste des compartiments S3 .  editing Origin

Au lieu de définir la source à partir du compartiment indiqué dans la liste déroulante, vous devez saisir le point de terminaison d'hébergement Web statique pour cette ressource à partir de la page de paramètres S3 et l'afficher manuellement.  where the static hosting endpoint url is

L’utilisation de la source statique pour la distribution Cloudfront Origin signifie que toute requête adressée à cette distribution utilisera la recherche d’objet racine de S3 et que vos réponses 404 devraient disparaître à mesure que les références circulent.

Important: Après cela, videz le cache de votre navigateur et dévaluez les éléments de votre distribution Cloudfront . Sinon, les modifications que vous avez apportées ne seront pas immédiatement mises en production.

10
Marc Guiselin

J'ai donc eu ce problème hier soir aussi.

Le problème est le suivant: S3 configuré en tant que compartiment de site Web pardonne et dont le paramètre de document d'index est défini sur index.html. Ce paramètre est appliqué à la racine. En d'autres termes, example.com est en fait redirigé vers example.com/index.html et il est également appliqué. au niveau des sous-dossiers, donc example.com/new ou example.com/new/ devrait tous deux être redirigé vers example.com/new/index.html, où il y aurait un objet dans le compartiment. (Sinon, vous obtiendrez une erreur NoSuchKey à la place.)

Cependant, vous passez ensuite à CloudFront, probablement pour HTTPS, et cette fonctionnalité disparaît. CloudFront effectue à la place des appels d'API explicites vers S3 et ne déclenche donc pas la concession de document d'index. Cela fonctionne pour la racine, mais pas pour les sous-dossiers.

La solution RoutingRules ne me semble pas propre car en spécifiant KeyPrefixEquals plutôt que key est exactement égal à (ce qui n'existe pas), je pense que vous obtiendrez des correspondances inattendues.

Au lieu de cela, j'ai implémenté une règle Lambda @ Edge qui réécrit la demande que CloudFront envoie à S3 pour qu'elle contienne une valeur de clé appropriée.

Commencez par les documents Lambda et l'exemple de test A/B ici: https://docs.aws.Amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-examples.html#lambda-examples-general-examples

Changer le code en:

'use strict';

exports.handler = (event, context, callback) => {
    /*
     * Expand S3 request to have index.html if it ends in /
     */
    const request = event.Records[0].cf.request;
    if ((request.uri !== "/") /* Not the root object, which redirects properly */
        && (request.uri.endsWith("/") /* Folder with slash */
            || (request.uri.lastIndexOf(".") < request.uri.lastIndexOf("/")) /* Most likely a folder, it has no extension (heuristic) */
            )) {
        if (request.uri.endsWith("/"))
            request.uri = request.uri.concat("index.html");
        else
            request.uri = request.uri.concat("/index.html");
    }
    callback(null, request);
};

Et publiez-le sur votre distribution CloudFront.

3
jkingok

Vous pouvez essayer de définir des règles de redirection. Voici une règle non testée. 

<RoutingRules>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>old</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <ReplaceKeyWith>old/index.html</ReplaceKeyWith>
    </Redirect>
  </RoutingRule>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>new</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <ReplaceKeyWith>new/index.html</ReplaceKeyWith>
    </Redirect>
  </RoutingRule>
</RoutingRules>
  1. Configurez votre seau pour fournir un site Web statique
  2. Créez une Distribution CloudFront : définissez votre compartiment en tant que Origin et laissez la OriginPath vide (valeur par défaut: /).
  3. Créez le Route53 RecordSet associé à votre Distribution CloudFront

Vous pouvez trouver une procédure utile ici _

Question: Que devrait-il se passer si votre client entre example.com (sans oldnew)?

Edit: 2. est facultatif. Vous pouvez également associer votre Route53 RecordSet à votre site Web statique _/mais CloudFront vous permet de servir votre site Web avec https (à l'aide de AWS Certificate Manager ).

0
MaiKaY