[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"blog-aws-cloudfront-部署靜態網站出現-x-cache-error-from-cloudfront-訊息":3},{"id":4,"slug":5,"title":6,"description":7,"content":8,"date":9,"image":10,"imageAlt":6,"author":11,"categories":14,"path":22,"minRead":23},3670,"aws-cloudfront-部署靜態網站出現-x-cache-error-from-cloudfront-訊息","AWS Cloudfront 部署靜態網站出現 X-cache: Error from cloudfront 訊息","AWS Cloudfront 部署靜態網站出現 x-cache: Error from cloudfront  […]","\u003Ch1>AWS Cloudfront 部署靜態網站出現 x-cache: Error from cloudfront 訊息\u003C\u002Fh1>\n\u003Cp>相關文章\u003Cbr \u002F>\n\u003Ca href=\"https:\u002F\u002Fstackoverflow.com\u002Fquestions\u002F59160472\u002Fhow-to-solve-x-cache-error-from-cloudfront-on-spa\">https:\u002F\u002Fstackoverflow.com\u002Fquestions\u002F59160472\u002Fhow-to-solve-x-cache-error-from-cloudfront-on-spa\u003C\u002Fa>\u003C\u002Fp>\n\u003Cp>\u003Ca href=\"https:\u002F\u002Fwww.withcoherence.com\u002Fpost\u002Faws-spa-routing-the-bad-the-ugly-and-the-uglier\">https:\u002F\u002Fwww.withcoherence.com\u002Fpost\u002Faws-spa-routing-the-bad-the-ugly-and-the-uglier\u003C\u002Fa>\u003C\u002Fp>\n\u003Cp>這個問題真的是恰巧才發現，也因此意識到不是瀏覽器看起來沒問題就好，網站建好後最好稍微掃一下標頭看看有沒有問題XD\u003C\u002Fp>\n\u003Cp>首先先敘述一下環境好了，這個專案建立在 AWS 上，使用了 S3 + Cloudfront 部署，是一個標準的靜態網站。只是因為業主需求，使用了子資料夾網域(sub-directory)，例如 https:\u002F\u002F\u003Cdoamin>\u002Fhome 。而我最終使用了 Html 5 的 \u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fdocs\u002FWeb\u002FAPI\u002FHistory?ref=blog.amowu.com\">History API\u003C\u002Fa> 來實作。某天剛好客戶做一些檢查發現跳紅字，就丟給我看，一看上面寫“X-cache: Error from cloudfront”，進而研究了一番。\u003C\u002Fp>\n\u003Ch2>什麼是 X-cache\u003C\u002Fh2>\n\u003Cp>X-cache 通常是 CDN 中會加入的一個標頭資訊，用來辨識你的請求是否由 CDN 傳出，如果成功狀態通常以 Hit 表示。\u003C\u002Fp>\n\u003Ch2>自定義錯誤頁面\u003C\u002Fh2>\n\u003Cp>如果使用過 Cloudfront 應該對這個設定不陌生，剛提到這專案使用了 \u003Ca href=\"https:\u002F\u002Fdeveloper.mozilla.org\u002Fdocs\u002FWeb\u002FAPI\u002FHistory?ref=blog.amowu.com\">History API\u003C\u002Fa> ，也因此要多設定 Cloufront 的自定義錯誤頁面(Custom Error Response)，不然會出現 404 Not Found 。\u003Cbr \u002F>\n設定方式很簡單：\u003C\u002Fp>\n\u003Col>\n\u003Cli>前往 CloudFront Distribution\u003C\u002Fli>\n\u003Cli>選擇 \u003Cstrong>Error Pages\u003C\u002Fstrong> 分頁籤，點選 \u003Cstrong>Create Custom Error Response\u003C\u002Fstrong> 建立自訂的錯誤回應\u003C\u002Fli>\n\u003Cli>HTTP Error Code 選擇 \u003Cstrong>404: Not Found\u003C\u002Fstrong>\u003C\u002Fli>\n\u003Cli>Error Caching Minimum TTL 輸入 \u003Cstrong>0\u003C\u002Fstrong>\u003C\u002Fli>\n\u003Cli>Customize Error Response 選擇 \u003Cstrong>Yes\u003C\u002Fstrong>\u003C\u002Fli>\n\u003Cli>Response Page Path 輸入 \u003Cstrong>\u002Findex.html\u003C\u002Fstrong>\u003C\u002Fli>\n\u003Cli>HTTP Response Code 選擇 \u003Cstrong>200: OK\u003C\u002Fstrong>\u003C\u002Fli>\n\u003Cli>設定完成\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>很多教學到這邊，多半以為大功告成了～我在遇到這問題前也以為這樣就好，結果發現“X-cache: Error from cloudfront”，什麼！根據 stackoverflow 中的討論，這訊息表示 CDN 可能是失效，也就是你享受不到 Cloudfront 的快取。透過種種資料，我的理解如下，原因在於當訪問網站 https:\u002F\u002F\u003Cdoamin>時，請求將命中 S3 的 index.html 檔案。因為使用了 History API ，而進入到 https:\u002F\u002F\u003Cdoamin>\u002Fhome 時，則不會有任何後端請求，因此重新載入後，會再次詢問有無 https:\u002F\u002F\u003Cdoamin>\u002Fhome\u002Findex.html 這隻檔案，瀏覽器就會認為有問題，但透過上述方式雖然強制給予 200 狀態，但 S3 會拋回錯誤，導致 Cloudfront 也出現錯誤(Error from cloudfront)。\u003C\u002Fp>\n\u003Ch2>使用 Cloudfront 函數\u003C\u002Fh2>\n\u003Cp>查到的解決做法就是在中介層強制拋回 \u002Findex.html ，實作可以透過 AWS 的 edge lambda function ，但更新的做法為 Cloudfront 自己的函數功能，流程如下：\u003C\u002Fp>\n\u003Col>\n\u003Cli>前往 CloudFront Distribution\u003C\u002Fli>\n\u003Cli>左側進入 函數\u003C\u002Fli>\n\u003Cli>建立新函數，我取名為 SPA-route\u003Cbr \u002F>\n\u003Cimg decoding=\"async\" src=\"\u002Fapi\u002Fproxy-image?url=https%3A%2F%2Fpost.billxu.net%2Fwp-content%2Fuploads%2F2024%2F03%2F%E6%88%AA%E5%9C%96-2024-03-11-%E4%B8%8B%E5%8D%883.37.51.png\" alt=\"\" \u002F>\u003C\u002Fli>\n\u003Cli>使用以下程式碼\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cpre>\u003Ccode class=\"language-jsx\">function handler(event){\n    \u002F\u002F Check if the request is for an internal route (doesn&#039;t have a file extension)\n    if (!event.request.uri.includes(&#039;.&#039;)) {\n        event.request.uri = &#039;\u002Findex.html&#039;; \n       }\n\n    return event.request;\n}\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Col>\n\u003Cli>在發布頁籤中，將要套用的分佈設定在關聯分佈中\u003C\u002Fli>\n\u003Cli>發布完成\u003C\u002Fli>\n\u003C\u002Fol>\n\u003Cp>大概幾分鐘後，就能看到”X-cache: Hit from cloudfront ”囉～\u003C\u002Fp>\n","2024-03-19T10:40:48","",{"name":12,"link":13},"Chih Fan","http:\u002F\u002Fpost.billxu.net",[15,17,20],{"name":16,"slug":16},"backend",{"name":18,"slug":19},"Devops","devops",{"name":21,"slug":21},"node","\u002Fblog\u002Faws-cloudfront-部署靜態網站出現-x-cache-error-from-cloudfront-訊息",1]