[CORS] POST 方法 Fetch 可以過,但是 Axios 無法

問題說明

「Fetch 可以過,但是 Axios 無法」的原因追根究底還是 CORS 造成的,只是 fetch 沒有帶上正確的參數,所以有不一樣的結果。

fetch 傳送的第二個參數中若沒有設定 headers 標示內容為 json 格式(application/json),會以文字格式傳送(text/plain),這屬於「簡單請求」,不會觸發 preflight 機制。

axios 傳入的資料如果是物件格式就會轉為 json,並且帶上對應的 header,所以會觸發 preflight 機制,當後端伺服器對 preflight 的回應沒有設置好時就會觸發瀏覽器的 cors 阻擋。


可能原因

  1. 後端沒有設置 cors header

    1
    'Access-Control-Allow-Origin': '*',
  2. 後端沒有設置 OPTIONS methods 或 response

    1
    2
    3
    'Access-Control-Allow-Methods': '...(其他方法).., OPTIONS',

    // 除 header 之外還要設置 OPTIONS 的回傳內容,不然可能被 40x 錯誤捕捉到。

檢查測試

  1. 確認瀏覽器錯誤訊息是否包含 preflight 的字眼。
    Access ..... has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.

  2. 確認 fetch 的請求內容是否有加上 header 參數。

    1
    2
    3
    headers: {
    'content-type': 'application/json'
    },
  3. 使用 Postman 發出 OPTIONS 請求,查看回應資訊。


解決方式

  • 正解:請後端加上 cors headers 或是確認 OPTIONS 的設置。
  • 暫時解:使用 CorsAnywhere、關閉瀏覽器 cors…等。

參考文章: