11

Con i servizi AWS abbiamo l'applicazione Web in esecuzione dal bucket S3 e l'accesso ai dati tramite l'API REST da Load Balancer (che è un insieme di applicazioni Node.js in esecuzione su un'istanza EC2).Come utilizzare S3 come pagina Web statica ed EC2 come API REST per esso insieme? (AWS)

Attualmente abbiamo specificato URL del seguente esempio:

  • API di Load Balancer:           api.somedomain.com
  • statico Web App su S3:             somedomain.com

Ma avere questa configurazione ci ha portato una serie di problemi in quanto le richieste sono CORS con questa configurazione. Potremmo risolvere il problema con CORS con intestazioni speciali, ma questo non funziona con tutti i browser.

Quello che vogliamo raggiungere è in esecuzione API sullo stesso dominio, ma con diverso percorso:

  • API Load Balancer:                     somedomain.com/api
  • Web App statica su S3:           somedomain.com

Una delle idee è stato quello di collegare l'API Load Balancer al CDN e inoltrare tutte le richieste di Load Balancer se interrogazione è in arrivo sul "/ api/*" percorso. Ma questo non funziona poiché la nostra API utilizza non solo le richieste HEAD e GET, ma anche POST, PUT, DELETE.

Un'altra idea è utilizzare la seconda istanza EC2 invece del bucket S3 per ospitare il sito Web (utilizzando alcuni server Web come nginx o apache). Ma questo dà troppe spese generali quando tutto è già in atto (hosting di contenuto statico S3). Inoltre, se si utilizza questo scenario non avremmo tutti i vantaggi delle prestazioni di Amazon CloudFront.

Quindi, potresti consigliare come combinare Load Balancer e S3, in modo che possano essere eseguiti sullo stesso dominio, ma con percorsi diversi? (API su somedomain.com/api e Web App su somedomain.com)

Grazie!

risposta

11

Non è possibile avere un'istanza EC2 e un bucket S3 con lo stesso nome host. Considera cosa succede quando un browser web fa una richiesta a quel nome host. DNS lo risolve in un indirizzo IP (o indirizzi) e i pacchetti della richiesta vengono consegnati a quell'indirizzo. L'indirizzo termina all'istanza EC2 o al bucket S3, non entrambi.

Come ho capito la situazione, sono presenti pagine Web statiche ospitate su S3 che includono codice JavaScript che effettua varie richieste HTTP all'istanza EC2. Se le pagine Web S3 si trovano su un host diverso rispetto all'istanza EC2, lo stesso criterio di origine impedirà al browser di tentare anche alcune richieste.

Le uniche soluzioni che posso vedere sono:

  • Fai tutte le richieste all'istanza EC2, con esso il recupero dei contenuti S3 e la consegna al browser ogni volta che una pagina web è chiesto.
  • Chiedi al tuo JavaScript di utilizzare iframe e cambiare document.domain nelle pagine web in un'origine madre comune. Ad esempio, se le tue pagine web sono a www.example.com e la tua istanza EC2 è a api.example.com, il codice JavaScript cambierebbe document.domain a example.com e il browser consentirebbe agli iframe da www.example.com di comunicare con api.example.com.
  • Mordere il proiettile e utilizzare CORS. Non è davvero difficile, e it's supported in tutti i browser recenti remoti (IE 8 e 9 lo fanno, ma non in modo standard).

Il primo metodo non va bene, perché in questo caso è quasi impossibile utilizzare S3.

Il secondo caso dovrebbe essere ok per voi. Dovrebbe funzionare in qualsiasi browser, perché non è davvero CORS. Quindi non servono intestazioni CORS. Ma è difficile.

Il terzo approccio CORS dovrebbe essere perfetto. La tua istanza EC2 deve solo restituire le intestazioni appropriate che dicono alle pagine Web dal bucket S3 che è sicuro per loro parlare con l'istanza EC2.

+0

Grazie per la vostra come una buona spiegazione! Probabilmente andremo con l'approccio CORS e creeremo soluzioni alternative per IE. – user1671010

+0

Felice di. Se questo risolve il tuo problema, contrassegnalo come risposta. –

0

Volevo solo aggiungere un ulteriore bit alla risposta che, se andiamo con l'approccio CORS e le richieste di preflight aggiungono un sovraccarico al server e alla larghezza di banda della rete, potremmo anche considerare di aggiungere l'intestazione "Access-Control-Max-Age" alla risposta CORS

Access-Control-Max-Age

Problemi correlati