Pexels Pixabay 355948

在跨網域存取(CORS)迷霧中的錯覺與啟示

在進行前後端分離架構的開發過程中,我們配置了`www.domain.site`作為前端展示頁面,並將`api.domain.site`設置為後端API服務。這種架構要求前端從不同的源發出請求到後端服務器,這裡就涉及到了跨域請求的處理。

為什麼有這篇

我的困擾來自於在實際測試中發現,當使用`application/json`與`application/x-www-form-urlencoded`這兩種不同的Content-Type進行POST請求時,行為竟然迥異。這讓我意識到了「簡單請求」和「預檢請求」之間的關鍵區別,並且整理出這篇內容,就是要分享我在這個過程中的探索與解決方法,希望能幫助同樣遇到此類問題的開發者。

簡單請求(Simple Requests)

當我們發送一個HTTP請求,如果該請求符合以下條件,則被認為是「簡單請求」:

  1. 使用GET、HEAD或POST方法。
  2. HTTP標頭限於幾種指定的欄位。
  3. 若有Content-Type,也僅限於三種:`text/plain`、`multipart/form-data`或`application/x-www-form-urlencoded`。

簡單請求不會觸發CORS預檢,因此,使用`application/x-www-form-urlencoded`時,我發現請求能夠直接發送且順利獲得回應。

預檢請求(Preflighted Requests)

但當我將Content-Type改為`application/json`,情況就大不相同了。這種設定下的請求不再被視為簡單請求,瀏覽器會首先發出一個OPTIONS請求作為預檢,向伺服器確認是否允許實際的請求。這就是我所說的「預檢請求」。

87ba0a0d 0099 42e6 9583 3c8e93a36162

解決方法

面對這個痛點,我們需要在後端服務器上進行適當的設定:

  1. 透過設置`Access-Control-Allow-Origin`來指明允許哪些來源的請求。
  2. 使用`Access-Control-Allow-Headers`來包含`Content-Type`,並明確允許`application/json`。
  3. 確保伺服器能夠處理OPTIONS方法的請求,並對這類預檢請求提供正確的CORS響應。
D0c36c10 C746 460a A187 28db27cbd328

要怎麼判斷CORS是否設定成功呢?你會注意到,在我分享的「預檢請求」截圖中,狀態欄顯示的204和我圈出來的「回傳204」實際上是指同一件事情。當你在網路開發者工具中看到「預檢請求」的狀態碼為204,這表示你的CORS的OPTIONS請求已經成功通過了。

這篇文章的撰寫,旨在分享我在處理跨域請求時的經驗心得。我希望透過我的探索與解決方案,能夠幫助到其他開發者,更有效地理解並處理跨域請求中遇到的問題。