[http] 不只是簡單的跨域請求 Preflight Request


Posted by vii120 on 2020-11-16

你給我翻譯翻譯,同一支 API 為何打了兩次

network xhr
不知大家是否有遇過,有時候 API 明明只調用了一次,卻會連續請求兩次
而且第一次請求時的類型不是 xhr,請求方法則是 OPTIONS
我是不是眼睛業障重!
api detail

讓 API 飛一會兒

先餵個估狗,發現在 CORS 情況下,且符合某些條件時 [註1](ex 有自定義的 request header)
在正式請求前,會多一個 preflight request(預檢請求)
目的是確認後續的跨站請求可以安全的送出,以多一層安全性保護
當預檢請求成功後,才會送出真正的請求
相反的,一般的跨域請求則為簡單請求(simple requests)

沒有錯誤,對我很重要

會發現 preflight request 這個小守衛是因為這個錯誤訊息:

Response to preflight request doesn’t pass access control check: Redirect is not allowed for a preflight request.

在開發時有隻 API 包含了自定義請求表頭,所以會觸發 preflight request
但同時該 API 內剛好有定義重新導向(redirect)
目前主流的瀏覽器們並不支援在 preflight request 時執行 redirect
因此在預檢請求時就報錯了,無法送出正式請求
(實測 chrome, firefox, safari 目前都不支援)

Request requires preflight, which is disallowed to follow cross-origin redirect

有幾種解決方法供參考:

  • 直接打 redirect 後的 API url
  • 拿掉 API 的 redirect 設定
  • 調整請求時的內容,避免觸發 preflight request

[註1] 會觸發 preflight request 的條件(符合下列任一)
  • http method 非 GET, POST, HEAD
  • request header 包含非 user agent 自動設定的標頭(Accept, Accept-Language, Content-Type, etc)
  • Content-Type 非 text/plain, multipart/form-dataapplication/x-www-form-urlencoded

參考資料

跨來源資源共用(CORS)#預檢請求 - HTTP | MDN


#cors #preflight #HTTP







Related Posts

(100Days Challenge of Python) Day5: For loop

(100Days Challenge of Python) Day5: For loop

[Py 百日馬 Day 2] Data Types

[Py 百日馬 Day 2] Data Types

相見恨晚的 chrome 插件 — Octotree - GitHub code tree

相見恨晚的 chrome 插件 — Octotree - GitHub code tree


Comments