Type something to search...
Chrome, AWS S3 and CORS

Chrome, AWS S3 and CORS

  • Web
  • 20 Jun, 2021

前陣子與公司的其他夥伴一起找出了偶發的 CORS 原因,紀錄一下

如果一個網站內有包含對同一個 URL 的載入,但是有兩種方式,一種是從 HTML document 載入,另一種是用 xhr 存取,並且 Chome 有開啟 cache,就有可能會遇到。

重現問題

例如下面這個簡單的範例,用兩種方式從 AWS cloudfont 抓取圖片,CDN 的來源是 AWS S3

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
<body>
  <img src="https://someawscdn.cloudfront.net/image.png">
  <script>
    setTimeout(function () {
      var oReq = new XMLHttpRequest();
      oReq.open("GET", "https://someawscdn.cloudfront.net/image.png");
      oReq.send();
    }, 5000);
  </script>
</body>
</html>

重現方式:

  • 打勾 Disable cache
  • 重新整理
  • 在 xhr 發出請求前把 Disable cache 取消勾選 備註:雖然 xhr 顯示在第一個,但其實是後面才發生的

原因

會出問題是因為 chrome 把從 img tag 先載入的 response 結果 cache 著,接著讓 xhr 使用 cache 的 response 回應,而因為這個 response 沒有 CORS 需要的 Header:access-control-allow-methodsaccess-control-allow-origin,所以就發生 CORS error。

https://zhuanlan.zhihu.com/p/38972475 提到原因是 AWS S3 在 request Header 沒有帶 Origin 時(像是 img tag),回應的 Header 不會包含 Vary: Origin,所以沒辦法讓 chrome 去區別緊接而來有帶 Origin 的 request,是不能使用 cache 回應的。

解決方式

可以讓 xhr 的 URL 帶上額外參數,讓 xhr 跟 image tag 使用的 URL 不同就可以。例如:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
  </head>
<body>
  <img src="https://someawscdn.cloudfront.net/image.png">
  <script>
    setTimeout(function () {
      var oReq = new XMLHttpRequest();
      oReq.open("GET", "https://someawscdn.cloudfront.net/image.png?cors=1");
      oReq.send();
    }, 5000);
  </script>
</body>
</html>

References

Share :

Related Posts

Fetch API 沒有傳送 cookies
Fetch API 沒有傳送 cookies

最近遇到一個案例,用戶明明有登入,但是打 API 時,卻因為沒有登入而噴錯。 在追查 HTTP Request/Response 時,眼尖的同事發現 Request Headers 根本沒有帶上 cookies,所以伺服器因為沒有 session 登入的資訊,所以才會當成 Client 端還沒登入。但奇怪的是 Client 端的網頁明明就是登入狀態。還有另一個線索是用戶的 Chrome 瀏覽器是

read more
玩玩看 KKBOX 與 Spotify 的 OAuth 2.0
玩玩看 KKBOX 與 Spotify 的 OAuth 2.0

心血來潮想玩看看 KKBOX 的 Open API,也一起測試了 Spotify 的部分。這次主要是試試看 OAuth 2.0 Authorization Code Flow 的授權流程,過程都是利用 Postman 來操作。 <LinkCard url="https://developer.spotify.com/documentation/general/guides/authoriza

read more
玩玩看 Spotify 的 Authorization Code Flow with PKCE
玩玩看 Spotify 的 Authorization Code Flow with PKCE

看到 Spotify 有支援另外一種 Authorization Code Flow,叫做 Authorization Code Flow with Proof Key for Code Exchange (PKCE),來玩玩看 Authorization Code Flow with PKCE 跟 Authorization Code Flow 的差異在於。為了怕使用者的 code 被中間人竊

read more