跳轉到

Same Origin Policy

瀏覽器基於安全性的考量所制定的規範

網站跟 API Server「不同源」的時候,瀏覽器一樣會幫你發送 Request,但會把 Response 給擋下來,不讓你的 JavaScript 拿到並傳回錯誤。

不同源之間如何互相傳輸資料?

  1. 關掉瀏覽器的安全性設置
  2. JSONP,JSON with Padding (<a>,<img>,<link>,<script>, <iframe> 不會受到 Same Origin Policy 限制)
  3. AJAX (ex: XMLHttpRequest, fetch) 搭配 後端設置 CORS header

Cross-Origin Resource Sharing (CORS)

CORS 將 Request 分成兩種:

1. 簡單請求

  • HEAD or GET or POST
  • HTTP Header 訊息在以下範圍內
  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type
  • Header 的 Content-Type 為:
  • text/plain
  • application/x-www-form-urlencoded
  • multipart/form-data

2. 非簡單請求

先透過對 OPTIONS method 的 Preflight Request 去確認後續的請求能否送出,如果 Preflight Request 沒有通過的話,真正的 Request 也就不會發送

為何需要 Preflight Request?

假設今天某個 Server 提供了一個 API ,網址為https://example.com/data/16,只要對它發送 GET,就能夠拿到 id 是 16 的資料,只要對它發送 DELETE,就可以把這筆資料刪除。

如果沒有 Preflight Request 這個機制的話,就可以隨便往一個 Domain 發送 DELETE 的 Request 給這支 API。雖然有CORS規範,但瀏覽器還是會幫你發送 Request,只是 Response 被瀏覽器擋住而已。因此儘管沒有 Response,Server 還是會把這筆資料刪除。

跨來源請求預設是不會把 cookie 帶上去的,需要在使用 xhr 或是 fetch 的時候多加一個參數,而後端也需要加一個額外的 header 才行

前端

credentials: 'include'

後端

  1. Access-Control-Allow-Origin 不能是 *,一定要明確指定 origin
  2. header 要帶上 Access-Control-Allow-Credentials: true

後端 1. header 要帶上 Access-Control-Expose-Headers