S3 Web Hosting statico Instrada tutti i percorsi verso Index.html


250

Sto usando S3 per ospitare un'app javascript che utilizzerà pushState HTML5. Il problema è che se l'utente aggiunge un segnalibro a uno degli URL, non risolverà nulla. Ciò di cui ho bisogno è la capacità di prendere tutte le richieste url e servire il root index.html nel mio bucket S3, piuttosto che semplicemente fare un reindirizzamento completo. Quindi la mia applicazione javascript potrebbe analizzare l'URL e servire la pagina corretta.

C'è un modo per dire a S3 di servire index.html per tutte le richieste URL invece di fare reindirizzamenti? Ciò sarebbe simile all'impostazione di apache per gestire tutte le richieste in arrivo offrendo un singolo index.html come in questo esempio: https://stackoverflow.com/a/10647521/1762614 . Vorrei davvero evitare di eseguire un server Web solo per gestire questi percorsi. Fare tutto da S3 è molto allettante.


Hai trovato una soluzione a questo?
w2lame

Risposte:


302

È molto facile risolverlo senza hack di url, con l'aiuto di CloudFront.

  • Creare un bucket S3, ad esempio: reagire
  • Crea distribuzioni CloudFront con queste impostazioni:
    • Oggetto root predefinito : index.html
    • Nome dominio di origine : dominio bucket S3, ad esempio: reazioni.s3.amazonaws.com
  • Vai alla scheda Pagine di errore , fai clic su Crea risposta di errore personalizzata :
    • Codice di errore HTTP : 403: vietato (404: non trovato, in caso di sito Web statico S3)
    • Personalizza la risposta all'errore : Sì
    • Percorso della pagina di risposta : /index.html
    • Codice di risposta HTTP : 200: OK
    • Clicca su Crea

8
Grazie. La migliore risposta finora.
jgb,

e ciò che non è così ovvio da mantenere la posizione in modo da poter eseguire il routing "naturale".
Lukasz Marek Sielski,

5
questo ha funzionato come un incantesimo per me, solo il codice di errore personalizzato di cui avevo bisogno era 404, non 403
Jeremy S.

4
Un po 'un trucco, ma funziona benissimo :) Sarebbe bello se CloudFront ci permettesse di mappare una serie di percorsi su un file S3 (senza reindirizzamento).
Bob,

3
Questo non funziona per me. Questa soluzione reindirizza sempre alla home page e non alle pagine corrette ...
Jim,

201

Il modo in cui sono riuscito a farlo funzionare è il seguente:

Nella sezione Modifica regole di reindirizzamento della console S3 per il tuo dominio, aggiungi le seguenti regole:

<RoutingRules>
  <RoutingRule>
    <Condition>
      <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
    </Condition>
    <Redirect>
      <HostName>yourdomainname.com</HostName>
      <ReplaceKeyPrefixWith>#!/</ReplaceKeyPrefixWith>
    </Redirect>
  </RoutingRule>
</RoutingRules>

Questo reindirizzerà tutti i percorsi che risultano in un 404 non trovato nel tuo dominio principale con una versione hash-bang del percorso. Quindi http://yourdomainname.com/posts reindirizzerà a http://yourdomainname.com/#!/posts a condizione che non vi sia alcun file in / posts.

Per utilizzare i pushState HTML5, tuttavia, dobbiamo prendere questa richiesta e stabilire manualmente il pushState corretto in base al percorso hash-bang. Quindi aggiungi questo nella parte superiore del tuo file index.html:

<script>
  history.pushState({}, "entry page", location.hash.substring(1));
</script>

Questo prende l'hash e lo trasforma in un pushState HTML5. Da questo punto in poi puoi usare pushStates per avere percorsi non hash-bang nella tua app.


4
Questa soluzione funziona alla grande! Infatti angularjs eseguirà automaticamente la cronologia pushState se la modalità HTML è configurata.
wcandillon,

1
Questo fallirà con la versione precedente di IE se hai parametri GET inclusi nei tuoi URL, giusto? Come aggirare quel problema?
clexmond,

3
Grazie! Questo ha funzionato bene per me sulla spina dorsale con una piccola modifica. Ho aggiunto un controllo per i browser più vecchi: <script language="javascript"> if (typeof(window.history.pushState) == 'function') { window.history.pushState(null, "Site Name", window.location.hash.substring(2)); } else { window.location.hash = window.location.hash.substring(2); } </script>
AE Grey,

10
Riuscì con react-routerquella soluzione usando HTML5 pushStates e<ReplaceKeyPrefixWith>#/</ReplaceKeyPrefixWith>
Felix D.

5
Non funziona in Safari ed è un grosso problema con la strategia di distribuzione. Scrivere un piccolo js per reindirizzare è una specie di approccio squallido. Inoltre, anche il numero di reindirizzamenti è un problema. Sto cercando di capire se c'è un modo per tutti gli URL S3 di puntare sempre a index.html.
moha297,

129

Ci sono alcuni problemi con l'approccio basato su S3 / Redirect menzionato da altri.

  1. I reindirizzamenti multipli avvengono quando vengono risolti i percorsi della tua app. Ad esempio: www.myapp.com/path/for/test viene reindirizzato come www.myapp.com/#/path/for/test
  2. È presente uno sfarfallio nella barra dell'URL quando il '#' va e viene a causa dell'azione del framework SPA.
  3. Il seo è influenzato perché - 'Ehi! Google sta forzando la sua mano sui reindirizzamenti
  4. Il supporto di Safari per la tua app va a segno.

La soluzione è:

  1. Assicurati di avere il percorso dell'indice configurato per il tuo sito web. Principalmente è index.html
  2. Rimuovere le regole di routing dalle configurazioni S3
  3. Metti un Cloudfront davanti al tuo secchio S3.
  4. Configura le regole della pagina di errore per l'istanza di Cloudfront. Nelle regole di errore specificare:

    • Codice di errore Http: 404 (e 403 o altri errori secondo necessità)
    • Errore memorizzazione nella cache TTL minimo (secondi): 0
    • Personalizza la risposta: Sì
    • Percorso della pagina di risposta: /index.html
    • Codice di risposta HTTP: 200

      1. Per esigenze SEO + assicurandoti che il tuo index.html non memorizzi nella cache, procedi come segue:
    • Configurare un'istanza EC2 e configurare un server nginx.

    • Assegna un IP pubblico alla tua istanza EC2.
    • Creare un ELB con l'istanza EC2 creata come istanza
    • Dovresti essere in grado di assegnare ELB al tuo DNS.
    • Ora, configura il tuo server nginx per fare le seguenti cose: Proxy_passare tutte le richieste al tuo CDN (solo per index.html, servire altre risorse direttamente dal tuo cloud) e per i bot di ricerca, reindirizzare il traffico come stabilito da servizi come Prerender.io

Posso aiutare in maggiori dettagli per quanto riguarda l'installazione di nginx, basta lasciare una nota. L'ho imparato nel modo più duro.

Una volta aggiornato l'aggiornamento della distribuzione del cloud. Invalida la cache del cloudfront una volta per accedere alla modalità originale. Premi l'URL nel browser e tutto dovrebbe andare bene.


6
poiché S3 risponde con un 403 Proibito quando non esiste un file, penso che il passaggio 4 sopra debba essere duplicato anche per il codice di errore Http 403
Andreas

4
Per me questa è l'unica risposta che si traduce in un comportamento atteso (accettato)
mabe.berlin

1
@ moha297 al punto 5 stai fondamentalmente configurando il tuo sito per recuperare da nginx che poi procede dal CDN (tranne per index.html e richieste del crawler)? In tal caso, non perderesti il ​​vantaggio dei edge server CDN?
Rahul Patel,

2
@ moha297 puoi per favore spiegare questo commento: "Non dovresti mai servire index.html da un CDN"? Non vedo il problema con la pubblicazione di index.html da S3 con CloudFront.
Carl G

1
Vedi stackoverflow.com/a/10622078/4185989 per maggiori informazioni su come viene trattato un TTL di 0 (versione breve: viene memorizzata nella cache da Cloudfront ma una If-Modified-Sincerichiesta GET viene inviata all'origine) - può essere una considerazione utile per le persone che non vogliono per configurare un server come nel passaggio 5.
jmq

18

È tangenziale, ma ecco un suggerimento per coloro che usano la libreria React Router di Rackt browser (HTML5) che vogliono ospitare su S3.

Supponiamo che un utente visiti il /foo/beartuo sito web statico ospitato su S3. Dato il precedente suggerimento di David , le regole di reindirizzamento le invieranno a /#/foo/bear. Se l'applicazione è stata creata utilizzando la cronologia del browser, questo non farà molto bene. Tuttavia, l'applicazione viene caricata a questo punto e ora può manipolare la cronologia.

Includendo la storia di Rackt nel nostro progetto (vedi anche Uso di storie personalizzate dal progetto React Router), puoi aggiungere un ascoltatore che è a conoscenza dei percorsi della cronologia dell'hash e sostituire il percorso come appropriato, come illustrato in questo esempio:

import ReactDOM from 'react-dom';

/* Application-specific details. */
const route = {};

import { Router, useRouterHistory } from 'react-router';
import { createHistory } from 'history';

const history = useRouterHistory(createHistory)();

history.listen(function (location) {
  const path = (/#(\/.*)$/.exec(location.hash) || [])[1];
  if (path) history.replace(path);
});

ReactDOM.render(
  <Router history={history} routes={route}/>,
  document.body.appendChild(document.createElement('div'))
);

Per ricapitolare:

  1. La regola di reindirizzamento S3 di David verrà indirizzata /foo/beara/#/foo/bear .
  2. Verrà caricata l'applicazione.
  3. Il listener della #/foo/bearcronologia rileverà la notazione della cronologia.
  4. E sostituisci la cronologia con il percorso corretto.

Linki tag funzioneranno come previsto, così come tutte le altre funzioni della cronologia del browser. L'unico aspetto negativo che ho notato è il reindirizzamento interstiziale che si verifica su richiesta iniziale.

Questo è stato ispirato da una soluzione per AngularJS e sospetto che possa essere facilmente adattato a qualsiasi applicazione.


2
Questo mi ha aiutato Michael, grazie! Potresti voler cambiare il tuo riferimento dalla cronologia e usare solo BrowserHistory. cioèbrowserHistory.listen
Marshall Moutenot il

Prego! Felice di aiutare. Inoltre, ho concordato e per questo particolare caso d'uso ho aggiornato lo snippet per risolvere un avviso di deprecazione da React Router.
Michael Ahlers,

Con il rilascio di Reaper-router v3.0.0 non funziona, poiché Reaper-router v3.0.0 utilizza la Storia v3.0.0
Varand Pezeshkian,

Qualche idea su come prevenire history.listen infinite call loop? Causato sostituendo il percorso immagino.
Mirko Flyktman,

14

Vedo 4 soluzioni a questo problema. I primi 3 erano già coperti da risposte e l'ultimo è il mio contributo.

  1. Impostare il documento di errore su index.html.
    Problema : il corpo della risposta sarà corretto, ma il codice di stato sarà 404, il che fa male alla SEO.

  2. Imposta le regole di reindirizzamento.
    Problema : URL inquinato #!e pagina lampeggia quando viene caricato.

  3. Configura CloudFront.
    Problema : tutte le pagine restituiranno 404 dall'origine, quindi è necessario scegliere se non si memorizzerà nella cache nulla (TTL 0 come suggerito) o se si memorizzerà nella cache e si avranno problemi durante l'aggiornamento del sito.

  4. Prerender tutte le pagine.
    Problema : lavoro aggiuntivo per le pagine del prerender, specialmente quando le pagine cambiano frequentemente. Ad esempio, un sito Web di notizie.

Il mio suggerimento è di utilizzare l'opzione 4. Se si effettua il pre-rendering di tutte le pagine, non ci saranno errori 404 per le pagine previste. La pagina verrà caricata correttamente e il framework prenderà il controllo e fungerà normalmente da SPA. È inoltre possibile impostare il documento di errore in modo da visualizzare una pagina error.html generica e una regola di reindirizzamento per reindirizzare gli errori 404 a una pagina 404.html (senza hashbang).

Per quanto riguarda gli errori 403 proibiti, non li lascio accadere affatto. Nella mia applicazione, ritengo che tutti i file all'interno del bucket dell'host siano pubblici e lo imposto con l' opzione Everyone con l' autorizzazione di lettura . Se il tuo sito ha pagine private, far vedere all'utente il layout HTML non dovrebbe essere un problema. Quello che devi proteggere sono i dati e questo viene fatto nel backend.

Inoltre, se disponi di risorse private, come le foto degli utenti, puoi salvarle in un altro bucket. Perché gli asset privati ​​richiedono la stessa cura dei dati e non possono essere confrontati con i file degli asset utilizzati per ospitare l'app.


1
e il tuo sito ha un ottimo esempio di utilizzo con prerender per tutte le pagine. zanon.io/posts/… .- Grazie
frekele

Questo quarto approccio si rivolge all'utente che ricarica l'URL pushState? Gestisce bene la navigazione ma, ricaricato, raggiungerà comunque il server.
Alpha,

@Alpha, non sono sicuro di aver compreso correttamente la tua domanda, ma su una ricarica, fungerebbe da nuova richiesta. S3 riceve la richiesta e restituisce nuovamente la pagina prerendered. Non esiste un server in questo caso.
Zanon,

@Zanon Ah, penso di aver capito. Ho pensato che avrebbe dovuto memorizzare nella cache le pagine prerendered ed evitare di utilizzare le risorse inesistenti di S3. Ciò tralascerebbe i percorsi con elementi dinamici, giusto?
Alpha,

1
@Zanon Finalmente capisco - grazie! Sì, questo è ciò che intendevo. :)
Alpha,

13

Ho riscontrato lo stesso problema oggi, ma la soluzione di @ Mark-Nutter era incompleta per rimuovere l'hashbang dalla mia applicazione angularjs.

In effetti devi andare su Modifica autorizzazioni , fai clic su Aggiungi altre autorizzazioni e quindi aggiungi l' elenco giusto sul tuo bucket a tutti. Con questa configurazione, AWS S3 ora sarà in grado di restituire l'errore 404 e quindi la regola di reindirizzamento rileverà correttamente il caso.

Proprio come questo : inserisci qui la descrizione dell'immagine

E quindi puoi andare a Modifica regole di reindirizzamento e aggiungere questa regola:

<RoutingRules>
    <RoutingRule>
        <Condition>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <HostName>subdomain.domain.fr</HostName>
            <ReplaceKeyPrefixWith>#!/</ReplaceKeyPrefixWith>
        </Redirect>
    </RoutingRule>
</RoutingRules>

Qui puoi sostituire HostName subdomain.domain.fr con il tuo dominio e KeyPrefix #! / Se non usi il metodo hashbang per scopi SEO.

Ovviamente, tutto questo funzionerà solo se hai già installato html5mode nella tua applicazione angolare.

$locationProvider.html5Mode(true).hashPrefix('!');

il mio unico problema con questo è che hai un lampo di hashbang, che non hai con qualcosa come una regola nginx. L'utente è su una pagina e aggiorna: / products / 1 -> #! / Products / 1 -> / products / 1
Intellix

1
Penso che dovresti aggiungere una regola per un errore 403 anziché concedere a tutti le autorizzazioni dell'elenco.
Hamish Moffatt,

11

La soluzione più semplice per far funzionare l'applicazione Angular 2+ da Amazon S3 e far funzionare gli URL diretti è specificare index.html sia come documenti Index che Error nella configurazione del bucket S3.

inserisci qui la descrizione dell'immagine


11
Questa è la stessa risposta di questa risposta fortemente retrocessa . Funziona bene, ma solo per bodyla risposta. Il codice di stato sarà 404 e danneggerà la SEO.
Zanon,

Perché questo funziona solo per bodyse hai degli script che stai importando in headessi non funzioneranno quando colpisci direttamente uno dei sotto-percorsi sul tuo sito web
Mohamed Hajr

4

dato che il problema è ancora lì, ho pensato di aggiungere un'altra soluzione. Il mio caso era che volevo distribuire automaticamente tutte le richieste pull su s3 per i test prima di unirle rendendole accessibili su [miodominio] / pull-richieste / [numero pr] /
(es. Www.example.com/pull-requests/822/ )

Per quanto ne so, gli scenari non basati su regole s3 consentirebbero di avere più progetti in un secchio usando il routing html5, quindi mentre il suggerimento più votato funziona per un progetto nella cartella principale, non per più progetti nelle proprie sottocartelle.

Quindi ho indirizzato il mio dominio sul mio server dove ha fatto il lavoro seguendo la configurazione di nginx

location /pull-requests/ {
    try_files $uri @get_files;
}
location @get_files {
    rewrite ^\/pull-requests\/(.*) /$1 break;
    proxy_pass http://<your-amazon-bucket-url>;
    proxy_intercept_errors on;
    recursive_error_pages on;
    error_page 404 = @get_routes;
}

location @get_routes {
    rewrite ^\/(\w+)\/(.+) /$1/ break;
    proxy_pass http://<your-amazon-bucket-url>;
    proxy_intercept_errors on;
    recursive_error_pages on;
    error_page 404 = @not_found;
}

location @not_found {
    return 404;
}

tenta di ottenere il file e, se non trovato, presuppone che sia una route html5 e ci prova. Se si dispone di una pagina angolare 404 per percorsi non trovati, non si arriva mai a @not_found e si restituisce la pagina 404 angolare anziché i file non trovati, che potrebbero essere corretti con alcune regole if in @get_routes o qualcosa del genere.

Devo dire che non mi sento troppo a mio agio nell'area della configurazione di nginx e usando regex per quel motivo, ho ottenuto questo lavoro con alcune prove ed errori, quindi mentre questo funziona sono sicuro che c'è spazio per miglioramenti e per favore condividi i tuoi pensieri .

Nota : rimuovere le regole di reindirizzamento di s3 se le si disponevano nella configurazione di S3.

e btw funziona in Safari


ciao .. grazie per la soluzione ... dove metti questo file conf nginx per la distribuzione di s3. è lo stesso del beanstalk elastico in cui devo creare la cartella .exextensions e inserirla nel file proxy.config?
user3124360,

@ user3124360 Non sono sicuro del beanstack elastico, ma nel mio caso punto il mio nome di dominio sull'istanza ec2 e ho la configurazione nginx lì. Quindi la richiesta va CLIENT -> DNS -> EC2 -> S3 -> CLIENT.
Andrew Arnautov,

si sto facendo qualcosa di molto simile ... con nginx config qui github.com/davezuko/react-redux-starter-kit/issues/1099 ... grazie per aver pubblicato il tuo file conf .. vedo come sviluppare questo EC2 -> Connessione S3 ora
user3124360

3

Stava cercando lo stesso tipo di problema. Ho finito per usare un mix delle soluzioni suggerite descritte sopra.

Innanzitutto, ho un bucket S3 con più cartelle, ogni cartella rappresenta un sito Web di reazione / redux. Uso anche cloudfront per invalidare la cache.

Quindi ho dovuto usare le regole di routing per supportare 404 e reindirizzarle a una configurazione hash:

<RoutingRules>
    <RoutingRule>
        <Condition>
            <KeyPrefixEquals>website1/</KeyPrefixEquals>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <Protocol>https</Protocol>
            <HostName>my.host.com</HostName>
            <ReplaceKeyPrefixWith>website1#</ReplaceKeyPrefixWith>
        </Redirect>
    </RoutingRule>
    <RoutingRule>
        <Condition>
            <KeyPrefixEquals>website2/</KeyPrefixEquals>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <Protocol>https</Protocol>
            <HostName>my.host.com</HostName>
            <ReplaceKeyPrefixWith>website2#</ReplaceKeyPrefixWith>
        </Redirect>
    </RoutingRule>
    <RoutingRule>
        <Condition>
            <KeyPrefixEquals>website3/</KeyPrefixEquals>
            <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
        </Condition>
        <Redirect>
            <Protocol>https</Protocol>
            <HostName>my.host.com</HostName>
            <ReplaceKeyPrefixWith>website3#</ReplaceKeyPrefixWith>
        </Redirect>
    </RoutingRule>
</RoutingRules>

Nel mio codice js, dovevo gestirlo con una baseNameconfigurazione per reagire-router. Prima di tutto, assicurati che le tue dipendenze siano interoperabili, che avevo installato e history==4.0.0che era incompatibile conreact-router==3.0.1 .

Le mie dipendenze sono:

  • "storia": "3.2.0",
  • "reagire": "15.4.1",
  • "reagire al flusso": "4.4.6",
  • "reagire-router": "3.0.1",
  • "reazioni-router-redux": "4.0.7",

Ho creato un history.jsfile per il caricamento della cronologia:

import {useRouterHistory} from 'react-router';
import createBrowserHistory from 'history/lib/createBrowserHistory';

export const browserHistory = useRouterHistory(createBrowserHistory)({
    basename: '/website1/',
});

browserHistory.listen((location) => {
    const path = (/#(.*)$/.exec(location.hash) || [])[1];
    if (path) {
        browserHistory.replace(path);
    }
});

export default browserHistory;

Questo pezzo di codice consente di gestire i 404 inviati dal server con un hash e sostituirli nella cronologia per caricare i nostri percorsi.

Ora puoi utilizzare questo file per configurare il tuo negozio e il tuo file radice.

import {routerMiddleware} from 'react-router-redux';
import {applyMiddleware, compose} from 'redux';

import rootSaga from '../sagas';
import rootReducer from '../reducers';

import {createInjectSagasStore, sagaMiddleware} from './redux-sagas-injector';

import {browserHistory} from '../history';

export default function configureStore(initialState) {
    const enhancers = [
        applyMiddleware(
            sagaMiddleware,
            routerMiddleware(browserHistory),
        )];

    return createInjectSagasStore(rootReducer, rootSaga, initialState, compose(...enhancers));
}
import React, {PropTypes} from 'react';
import {Provider} from 'react-redux';
import {Router} from 'react-router';
import {syncHistoryWithStore} from 'react-router-redux';
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import variables from '!!sass-variable-loader!../../../css/variables/variables.prod.scss';
import routesFactory from '../routes';
import {browserHistory} from '../history';

const muiTheme = getMuiTheme({
    palette: {
        primary1Color: variables.baseColor,
    },
});

const Root = ({store}) => {
    const history = syncHistoryWithStore(browserHistory, store);
    const routes = routesFactory(store);

    return (
        <Provider {...{store}}>
            <MuiThemeProvider muiTheme={muiTheme}>
                <Router {...{history, routes}} />
            </MuiThemeProvider>
        </Provider>
    );
};

Root.propTypes = {
    store: PropTypes.shape({}).isRequired,
};

export default Root;

Spero che sia d'aiuto. Noterai con questa configurazione che uso l'iniettore redux e un iniettore saghe homebrew per caricare javascript in modo asincrono tramite routing. Non importa con queste righe.


3

Ora puoi farlo con Lambda @ Edge per riscrivere i percorsi

Ecco una funzione lambda @ Edge funzionante:

  1. Crea una nuova funzione Lambda, ma usa uno dei progetti preesistenti invece di una funzione vuota.
  2. Cerca "cloudfront" e seleziona la generazione di risposta cloudfront dai risultati della ricerca.
  3. Dopo aver creato la funzione, sostituire il contenuto con il seguente. Ho anche dovuto modificare il runtime del nodo su 10.x perché cloudfront non supportava il nodo 12 al momento della scrittura.
'use strict';
exports.handler = (event, context, callback) => {

    // Extract the request from the CloudFront event that is sent to Lambda@Edge 
    var request = event.Records[0].cf.request;

    // Extract the URI from the request
    var olduri = request.uri;

    // Match any '/' that occurs at the end of a URI. Replace it with a default index
    var newuri = olduri.replace(/\/$/, '\/index.html');

    // Log the URI as received by CloudFront and the new URI to be used to fetch from origin
    console.log("Old URI: " + olduri);
    console.log("New URI: " + newuri);

    // Replace the received URI with the URI that includes the index page
    request.uri = newuri;

    return callback(null, request);
};

Nei tuoi comportamenti cloudfront, li modificherai per aggiungere una chiamata a quella funzione lambda su "Richiesta visualizzatore" inserisci qui la descrizione dell'immagine

Tutorial completo: https://aws.amazon.com/blogs/compute/implementing-default-directory-indexes-in-amazon-s3-backed-amazon-cloudfront-origins-using-lambdaedge/


1
Nell'esempio di codice manca solo una riga:return callback(null, request);
Pherrymason

2

Se sei arrivato qui alla ricerca di una soluzione che funzioni con React Router e AWS Amplify Console: sai già che non puoi utilizzare le regole di reindirizzamento di CloudFront direttamente poiché Amplify Console non espone la distribuzione di CloudFront per l'app.

La soluzione, tuttavia, è molto semplice: devi solo aggiungere una regola di reindirizzamento / riscrittura in Amplify Console in questo modo:

Amplifica la regola di riscrittura della console per React Router

Vedere i seguenti collegamenti per ulteriori informazioni (e regola di copia semplificata dallo screenshot):


0

Stavo cercando una risposta a me stesso. S3 sembra supportare solo i reindirizzamenti, non puoi semplicemente riscrivere l'URL e restituire silenziosamente una risorsa diversa. Sto pensando di usare il mio script di build per fare semplicemente copie del mio index.html in tutte le posizioni del percorso richieste. Forse funzionerà anche per te.


2
Anche la generazione di file di indice per ogni percorso mi è passata per la testa, ma sarebbe difficile avere percorsi dinamici come example.com/groups/5/show . Se vedi la mia risposta a questa domanda, credo che risolva il problema per la maggior parte. È un po 'un trucco ma almeno funziona.
Mark Nutter,

Meglio distribuire dietro un server nginx e restituire index.html per tutti gli URL in arrivo. L'ho fatto con successo con la distribuzione heroku di app di brace.
moha297,

-3

Giusto per dare la risposta estremamente semplice. Usa la strategia di localizzazione dell'hash per il router se stai ospitando su S3.

export const AppRoutingModule: ModuleWithProviders = RouterModule.forRoot (route, {useHash: true, scrollPositionRestoration: 'enabled'});

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.