Same Origin Policy
瀏覽器基於安全性的考量所制定的規範
網站跟 API Server「不同源」的時候,瀏覽器一樣會幫你發送 Request,但會把 Response 給擋下來,不讓你的 JavaScript 拿到並傳回錯誤。
不同源之間如何互相傳輸資料?
關掉瀏覽器的安全性設置- JSONP,JSON with Padding
(<a>,<img>,<link>,<script>, <iframe> 不會受到 Same Origin Policy 限制)
- 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
跨來源請求預設是不會把 cookie 帶上去的,需要在使用 xhr 或是 fetch 的時候多加一個參數,而後端也需要加一個額外的 header 才行
前端
credentials: 'include'
後端
Access-Control-Allow-Origin 不能是 *,一定要明確指定 origin
- header 要帶上
Access-Control-Allow-Credentials: true
如何存取自定義 header
後端 1. header 要帶上 Access-Control-Expose-Headers