2012-09-19 54 views
31

要點:緩存非CORS響應衝突請求

我有一個從S3(HTML img標籤)使用的圖像的代碼加載一個網頁,我有一個使用xmlhttprequest的頁面。標籤加載得到緩存而沒有CORS頭,因此xmlhttprequest看到緩存版本,檢查它的頭文件並失敗並出現交叉原點錯誤。

詳情:

編輯:在失敗對Safari 5.1.6和Chrome 21.0.1180.89。在Firefox 14

使用S3的新CORS,我設置一個CORSRule爲使工作正常:

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

如果我要求從S3圖像不用設置原點的請求頭,我回去的圖像,而不響應中的任何CORS標題。

由於瀏覽器使用緩存中的非CORS版本,此get的緩存和隨後的CORS請求(一個用於設置請求頭中原點的請求)將被拒絕。

解決此問題的最佳方法是什麼?我可以設置一些東西,這樣非CORS版本永遠不會被緩存嗎?我應該通過將?some_flag附加到請求的URL來區分CORS請求嗎?

理想情況下,即使請求中不包含「origin」,我也會讓S3始終發送所需的CORS頭文件。

+0

你使用什麼瀏覽器?這種行爲是否發生在所有瀏覽器中?這聽起來像是一個瀏覽器錯誤。您提出的查詢參數解決方案聽起來像是一個很好的解決方法。 – monsur

+0

添加「編輯:在safari 5.1.6和chrome 21.0.1180.89都失敗了。在firefox 14中工作正常。」 – Wes

+1

然後可能是一個WebKit錯誤。這聽起來像是同樣的問題:https://bugs.webkit.org/show_bug.cgi?id=63090該錯誤表明,添加標頭「Vary:Origin」可能會解決該問題。 – monsur

回答

7

我遇到了同樣的問題。正如@monsur所說,問題在於S3並沒有設置「Vary:Origin」標題,即使它應該。不幸的是,據我所知,沒有辦法讓S3發送這個頭文件。但是,您可以通過在需要CORS時向請求添加查詢字符串參數(例如?origin=example.com)來解決此問題。查詢字符串強制瀏覽器不使用緩存資源。

理想情況下,當CORS被啓用時,cloudfront和S3會發送Vary:Origin頭文件,並且/或者Webkit會在Origin頭文件中隱含地變化,我假設Firefox沒有這個問題。

6

這絕對不是最好的方法,但是您可以通過向請求添加一些url參數來禁用圖像請求的緩存。通常,這是通過JavaScript實現,例如:

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

這將始終強制未緩存的響應,因爲以毫秒爲單位的日期總是產生不同的URL,瀏覽器還不知道,但我不確定是否這解決了你的問題。

0

在發出CORS請求後,您可以使用Javascript附加img標籤。

0

一個解決辦法是設置在img -tag的crossorigin='use-credentials'屬性強制瀏覽器始終執行CORS的要求,在這裏看到:https://stackoverflow.com/a/34496683/725542

另一個解決方案是配置您的CloudFront的分佈自動打開非CORS請求進入CORS請求。通過爲CloudFront使用最近添加的CloudFront功能「控制邊緣至原始請求頭」發送至S3的每個請求添加CORS頭,可以實現此目的。

見特徵通知在這裏:https://aws.amazon.com/blogs/aws/cloudfront-update-https-tls-v1-1v1-2-to-the-origin-addmodify-headers/

這裏的文檔:http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/forward-custom-headers.html

0

我也遇到了這個問題。我最終在我的S3存儲桶前設置了一個cloudfront分佈,並在cloudfront的Origin Settings部分中設置Origin Custom Headers選項,以將Origin: https://example.com發送到我的S3原點。這會導致S3始終服務於CORS標題,因爲它始終會看到Origin請求標頭。爲此,您必須確保Origin標題未被您的任何雲端行爲列入白名單。

tl; dr:我告訴雲端發送Origin: https://example.com與我的S3起源的每個請求,並通過雲端服務我的內容。