2017-03-02 107 views
0

我正在通過S3和Cloudfront爲通過靜態站點生成器生成的網站提供服務。正在使用正確的內容類型將文件上傳到S3。 DNS指向使用S3存儲桶作爲其原點的Cloudfront。 Cloudfront關心加密和壓縮。我告訴Cloudfront自動壓縮對象。這工作得很好,直到我決定將一些使用過的圖像從PNG更改爲SVG。Cloudfront對壓縮和未壓縮文件使用不同的Content-Type

每當一個文件被請求解壓縮時,它就像設置的Content-Type(image/svg + xml)一樣被傳遞並且該站點被正確地渲染。但是,如果文件被請求爲壓縮文件,則它將與默認的Content-Type(應用程序/八位字節流)一起交付,並且圖像在渲染中丟失。如果我然後右鍵單擊圖像並選擇在新選項卡中打開圖像,它將顯示正確(沒有頁面的其餘部分)。

結果與使用的瀏覽器無關。在Firefox中,我知道如何將它設置爲強制請求壓縮或未壓縮的頁面。我也嘗試捲曲檢查標題。這些結果如下:

λ curl --compressed -v -o /dev/null http://dev.example.com/img/logo-6998bdf68c.svg 
* STATE: INIT => CONNECT handle 0x20049798; line 1090 (connection #-5000) 
* Added connection 0. The cache now contains 1 members 
* Trying 52.222.157.200... 
* STATE: CONNECT => WAITCONNECT handle 0x20049798; line 1143 (connection #0) 
    % Total % Received % Xferd Average Speed Time Time  Time Current 
           Dload Upload Total Spent Left Speed 
    0  0 0  0 0  0  0  0 --:--:-- --:--:-- --:--:--  0* Connected to dev.example.com (52.222.157.200) port 80 (#0) 
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x20049798; line 1240 (connection #0) 
* STATE: SENDPROTOCONNECT => DO handle 0x20049798; line 1258 (connection #0) 
> GET /img/logo-6998bdf68c.svg HTTP/1.1 
> Host: dev.example.com 
> User-Agent: curl/7.44.0 
> Accept: */* 
> Accept-Encoding: deflate, gzip 
> 
* STATE: DO => DO_DONE handle 0x20049798; line 1337 (connection #0) 
* STATE: DO_DONE => WAITPERFORM handle 0x20049798; line 1464 (connection #0) 
* STATE: WAITPERFORM => PERFORM handle 0x20049798; line 1474 (connection #0) 
* HTTP 1.1 or later with persistent connection, pipelining supported 
< HTTP/1.1 200 OK 
< Content-Type: application/octet-stream 
< Content-Length: 7468 
< Connection: keep-alive 
< Date: Wed, 01 Mar 2017 13:31:33 GMT 
< x-amz-meta-cb-modifiedtime: Wed, 01 Mar 2017 13:28:26 GMT 
< Last-Modified: Wed, 01 Mar 2017 13:30:24 GMT 
< ETag: "6998bdf68c8812d193dd799c644abfb6" 
* Server AmazonS3 is not blacklisted 
< Server: AmazonS3 
< X-Cache: RefreshHit from cloudfront 
< Via: 1.1 36c13eeffcddf77ad33d7874b28e6168.cloudfront.net (CloudFront) 
< X-Amz-Cf-Id: jT86EeNn2vFYAU2Jagj_aDx6qQUBXFqiDhlcdfxLKrj5bCdAKBIbXQ== 
< 
{ [7468 bytes data] 
* STATE: PERFORM => DONE handle 0x20049798; line 1632 (connection #0) 
* Curl_done 
100 7468 100 7468 0  0 44526  0 --:--:-- --:--:-- --:--:-- 48493 
* Connection #0 to host dev.example.com left intact 
* Expire cleared 

和未壓縮它看起來更好:

λ curl -v -o /dev/null http://dev.example.com/img/logo-6998bdf68c.svg 
* STATE: INIT => CONNECT handle 0x20049798; line 1090 (connection #-5000) 
* Added connection 0. The cache now contains 1 members 
* Trying 52.222.157.203... 
* STATE: CONNECT => WAITCONNECT handle 0x20049798; line 1143 (connection #0) 
    % Total % Received % Xferd Average Speed Time Time  Time Current 
           Dload Upload Total Spent Left Speed 
    0  0 0  0 0  0  0  0 --:--:-- --:--:-- --:--:--  0* Connected to dev.example.com (52.222.157.203) port 80 (#0) 
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x20049798; line 1240 (connection #0) 
* STATE: SENDPROTOCONNECT => DO handle 0x20049798; line 1258 (connection #0) 
> GET /img/logo-6998bdf68c.svg HTTP/1.1 
> Host: dev.example.com 
> User-Agent: curl/7.44.0 
> Accept: */* 
> 
* STATE: DO => DO_DONE handle 0x20049798; line 1337 (connection #0) 
* STATE: DO_DONE => WAITPERFORM handle 0x20049798; line 1464 (connection #0) 
* STATE: WAITPERFORM => PERFORM handle 0x20049798; line 1474 (connection #0) 
* HTTP 1.1 or later with persistent connection, pipelining supported 
< HTTP/1.1 200 OK 
< Content-Type: image/svg+xml 
< Content-Length: 7468 
< Connection: keep-alive 
< Date: Wed, 01 Mar 2017 20:56:11 GMT 
< x-amz-meta-cb-modifiedtime: Wed, 01 Mar 2017 20:39:17 GMT 
< Last-Modified: Wed, 01 Mar 2017 20:41:13 GMT 
< ETag: "6998bdf68c8812d193dd799c644abfb6" 
* Server AmazonS3 is not blacklisted 
< Server: AmazonS3 
< Vary: Accept-Encoding 
< X-Cache: RefreshHit from cloudfront 
< Via: 1.1 ac27d939fa02703c4b28926f53f95083.cloudfront.net (CloudFront) 
< X-Amz-Cf-Id: AlodMvGOKIoNb8zm5OuS7x_8TquQXzAAXg05efSMdIKgrPhwEPv4kA== 
< 
{ [2422 bytes data] 
* STATE: PERFORM => DONE handle 0x20049798; line 1632 (connection #0) 
* Curl_done 
100 7468 100 7468 0  0 27667  0 --:--:-- --:--:-- --:--:-- 33639 
* Connection #0 to host dev.example.com left intact 

我不想關掉壓縮性能的原因。看起來這隻發生在SVG文件類型上。所有其他類型都有正確的,即。相同的內容類型。我已經試圖使緩存失效,甚至通過將緩存時間設置爲0秒來完全關閉緩存。上傳到S3時,我無法上傳壓縮版本,因爲上傳過程是自動的,不能輕易更改爲單個文件。

我希望我做了錯誤的事情,因爲那樣最容易被修復。但我不知道這個設置有什麼問題。我已經使用Google找到有類似問題的人,但它看起來只有我。任何人,誰有想法?

+0

嘗試將壓縮的圖像從.svg重命名爲.svgz –

+0

我認爲這是問題所在。但我不壓縮。 Cloudfront會執行所有壓縮操作,並且壓縮文件不會存儲在S3上。它們用於存儲在Cloudfront邊緣的緩存時間。如果客戶端請求Content-Encoding:gzip,deflate,Cloudfront會進行壓縮。 – adcgn

回答

0

你錯誤地診斷了這個問題。 CloudFront不更改Content-Type

但是,根據請求的變化,CloudFront會緩存同一對象的不同版本。

如果你發現,你的Last-Modified倍這些對象是不同的。您最初在S3中將內容類型設置錯誤。隨後你修正了這個問題,但是CloudFront沒有意識到元數據已經改變,因爲ETag沒有改變,所以你得到的錯誤回覆爲RefreshHit。它針對宣傳gzip編碼支持的請求提供舊版本。如果對象的實際有效負載已更改,則CloudFront可能已更新其緩存。

做一個invalidation清除緩存,並在幾分鐘內,這個問題應該消失。