2015-07-30 8 views
14

Sto utilizzando un bucket S3 dietro Cloudfront con CORS abilitato. Se il client effettua una richiesta con l'intestazione Origin, S3 (e cloudfront) rispondono con un'intestazione "Vary: Origin", tuttavia se la richiesta viene eseguita senza l'intestazione Origin, la risposta non contiene alcun Vary Header.S3 CORS, invia sempre Varia: Origine

Ciò è problematico poiché utilizzo una risorsa da cloudfront/s3 in un tag img, nel qual caso il browser effettua la richiesta senza l'intestazione Origin e quindi effettua una richiesta ajax per detta immagine. Il browser utilizza quindi la versione cache dell'immagine, senza l'intestazione Access-Control-Allow-Origin e quindi rifiuta la richiesta.

C'è un modo per far sì che S3 restituisca sempre l'intestazione "Vary: Origin"?

+4

Il problema è stato segnalato anche nei [Forum AWS] (https://forums.aws.amazon.com/thread.jspa?messageID=555417򇦙) –

risposta

6

Un'altra soluzione sarebbe la configurazione della distribuzione CloudFront per trasformare automaticamente le richieste Non-CORS in richieste CORS. Ciò è possibile aggiungendo un'intestazione CORS a ciascuna richiesta che CloudFront invia a S3 utilizzando la funzionalità CloudFront aggiunta di recente "Intestazioni di richiesta di controllo origine-origine".

Vedere l'annuncio funzione qui: https://aws.amazon.com/blogs/aws/cloudfront-update-https-tls-v1-1v1-2-to-the-origin-addmodify-headers/

E la documentazione qui: http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/forward-custom-headers.html.

+1

Bello, questo forzerà Access-Control-Allow-Origin ma per Vary: Origin? – caub

+1

Se si impone Access-Control-Allow-Origin su ogni richiesta, "Vary: Origin" non è più necessario, poiché l'intestazione non varia più a seconda delle richieste. Non è più problematico se il browser utilizza una versione memorizzata nella cache, poiché anche questa versione è abilitata per CORS. –

+1

Tuttavia, se imponi a CloudFront di inviare sempre "Origine: X.dominio.com" a S3, non c'è modo per CloudFront di restituire "Access-Control-Allow-Origin: Y.domain.com". In altre parole, questa soluzione di intestazione forza funziona solo se si restituisce un'intestazione di risposta con caratteri jolly "Access-Control-Allow-Origin: *" o solo sempre restituisce un dominio _single_ nella nostra intestazione "Access-Control-Allow-Origin". – timmfin

10

Ho creato un account solo per rispondere alla tua domanda, perché ci sono poche risposte valide in giro per questo tipo di problema (e alcuni correlati).

Il problema che si descrive avviene per qualche motivo principalmente in chrome, FF e IE sembra essere abbastanza intelligente da non condividere la cache tra AJAX e le chiamate regolari in queste istanze.

Il problema

Consente prima di descrivere il motivo per cui il problema si verifica per i futuri lettori:

  • browser (Chrome) chiedere al server utilizzando un normale tag <img> o <script>. Se il server si trova nello stesso dominio, non include le intestazioni CORS.
  • Il server (S3) restituisce la risorsa. Se nella richiesta non era presente un'intestazione di origine, nella risposta non vengono allegate le intestazioni CORS in quanto sono ridondanti.
  • Browser (Chrome) tenta di richiamare la risorsa utilizzando AJAX, ma questa volta non raggiunge il server ma esamina la risorsa memorizzata nella cache.
  • Browser (Chrome) La versione memorizzata nella cache non ha intestazioni CORS. Eliminerà la richiesta come violazione di Access-Control-Allow-Origin o altri problemi correlati.

La soluzione

in HTML5 non è un attributo chiamato crossorigin che può essere aggiunto ai tag per indicare che hanno bisogno di inviare le informazioni di origine. valori possibili sono crossorigin='anonymous' e crossorigin='use-credentials' questi sono abbastanza irrilevante per la questione ha chiesto, ma come si dice nella documentazione:

Per default (cioè, quando l'attributo non è specificato), CORS non viene utilizzato affatto.

https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes

Così appena Crea il tuo tag di immagine come questo <img src='cloundfront.path' crossorigin='use-credentials'>

questo è tutto. È piuttosto oscuro quindi spero che questa risposta risparmi tempo di ricerca per un gruppo di persone.

+0

Avrei ragione ad assumere che 'crossorigin =" use-credentials "' sarebbe equivalente a chiamare 'withCredentials' su una richiesta XHR? In tal caso, 'crossorigin =" anonymous "' funziona altrettanto bene, per quanto riguarda il fatto di assicurarsi che le intestazioni di CORS vengano restituite? Preferirei non permettere alle mie immagini statiche di fare cose come i cookie di set se posso aiutarlo. –

Problemi correlati