2012-09-19 13 views
31

Gist:conflitti risposta in cache non CORS con nuove CORS richiedere

ho una pagina che utilizza tag di caricamento di un'immagine da S3 (HTML img tag) e ho una pagina che utilizza xmlhttprequest. Il caricamento dei tag viene memorizzato nella cache senza le intestazioni CORS e quindi lo xmlhttprequest vede la versione memorizzata nella cache, controlla le intestazioni e fallisce con un errore di origine incrociata.

Dettagli:

modificare: non riesce in entrambi Safari 5.1.6 e Chrome 21.0.1180.89. Funziona bene in Firefox 14.

Utilizzando nuove CORS di S3, a configurare una CORSRule come così:

<CORSRule> 
    <AllowedOrigin>*</AllowedOrigin> 
    <AllowedMethod>GET</AllowedMethod> 
    <AllowedMethod>HEAD</AllowedMethod> 
    <MaxAgeSeconds>0</MaxAgeSeconds> 
    <AllowedHeader>*</AllowedHeader> 
</CORSRule> 

Se richiedo un'immagine da S3 senza impostare l'origine nelle intestazioni di richiesta torno l'immagine senza eventuali intestazioni CORS nella risposta.

Questa richiesta viene memorizzata nella cache e le successive richieste CORS (le quali impostano l'origine nell'intestazione della richiesta) vengono rifiutate poiché il browser utilizza la versione non CORS della cache.

Qual è il modo migliore per risolvere questo problema? Posso impostare qualcosa in modo che la versione non CORS non venga mai salvata nella cache? Devo differenziare le richieste CORS aggiungendo un ?some_flag all'URL della richiesta?

Idealmente avrei S3 SEMPRE inviare le intestazioni CORS necessarie anche se la richiesta non contiene "origine".

+0

Che browser stai utilizzando? Questo comportamento si verifica in tutti i browser? Sembra un bug del browser. La soluzione del parametro di query che proponi sembra una buona soluzione. – monsur

+0

aggiunto "edit: errore in entrambi i safari 5.1.6 e chrome 21.0.1180.89. Funziona bene in firefox 14." – Wes

+1

Probabilmente un bug WebKit allora. Sembra lo stesso problema: https://bugs.webkit.org/show_bug.cgi?id=63090 Il bug suggerisce che l'aggiunta dell'intestazione "Vary: Origin" potrebbe risolvere il problema. – monsur

risposta

7

Mi sono imbattuto nello stesso problema. Come ha detto @monsur, il problema è che S3 non imposta l'intestazione "Vary: Origin", anche se dovrebbe. Sfortunatamente, per quanto ne so, non c'è modo di convincere S3 a inviare quell'intestazione. Tuttavia, è possibile aggirare questo problema aggiungendo un parametro di stringa di query alla richiesta, ad esempio ?origin=example.com quando è necessario CORS. La stringa di query forza il browser a non utilizzare la risorsa memorizzata nella cache.

Idealmente, cloudfront e S3 inviano l'intestazione Vary: Origin quando CORS è abilitato e/o Webkit varia implicitamente sull'intestazione Origin, che presumo che Firefox funzioni poiché non presenta questo problema.

6

non è sicuramente il modo migliore, ma è possibile disabilitare la memorizzazione nella cache della richiesta di immagine aggiungendo qualche parametro url alla richiesta. Di solito, questo viene fatto tramite JavaScript, ad esempio:

var img = document.createElement('img'); 
img.setAttribute('src', yourRequestUrl + '?d=' + Date.now()); 
tagToAppendImg.appendChild(img); 

questo sarà sempre forzare una risposta non memorizzata nella cache, perché la data in millisecondi produce sempre un URL diverso che il browser non lo sa ancora, ma io sono incerti se questo risolve il tuo problema.

0

È possibile aggiungere il tag img utilizzando Javascript dopo aver richiesto CORS.

0

Una soluzione potrebbe essere quella di impostare l'attributo crossorigin='use-credentials' sul img -tag per forzare il browser di eseguire sempre una richiesta CORS, vedi qui: https://stackoverflow.com/a/34496683/725542

Un'altra soluzione sarebbe configurando la vostra distribuzione CloudFront di trasformare automaticamente Non- Richieste 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.

0

Ho incontrato anche questo problema. Ho finito per impostare una distribuzione di cloudfront davanti al mio bucket S3 e impostare le opzioni Origin Custom Headers nella sezione Origin Settings in cloudfront per inviare Origin: https://example.com all'origine S3. Questo fa sì che S3 serva sempre le intestazioni CORS, poiché vede sempre l'intestazione della richiesta Origin. Per fare ciò, devi assicurarti che l'intestazione Origin non sia autorizzata da nessuno dei tuoi comportamenti di cloudfront.

tl; dr: Ho detto a cloudfront di inviare Origin: https://example.com con ogni richiesta alla mia origine S3 e fornito il mio contenuto tramite cloudfront.

Problemi correlati