想要回答這個問題需要先明白什麼是簡單請求和非簡單請求
瀏覽器請求方式可以劃分爲簡單請求和非簡單請求
簡單請求
簡單請求你可以理解為那些不會對伺服器造成風險的請求。根據 CORS(跨源資源共享,Cross-Origin Resource Sharing) 的定義,簡單請求必須滿足以下條件:
使用
GET
、POST
或HEAD
方法。僅包含少量特定的請求頭部,如
Accept
、Accept-Language
、Content-Language
、Content-Type
(但只能是application/x-www-form-urlencoded
、multipart/form-data
或text/plain
)。不包含自定義的請求頭部(即除了瀏覽器預設的上面那些)。
非簡單請求
不滿足簡單請求的條件就是非簡單請求
除了
GET
、POST
和HEAD
之外的其他 HTTP 方法都會導致請求變成非簡單請求,例如:
PUT
DELETE
PATCH
任何不在簡單請求頭部列表中的頭部,或者
Content-Type
不是application/x-www-form-urlencoded
、multipart/form-data
或text/plain
的情況,都會導致請求變成非簡單請求。例如:
Authorization
X-Custom-Header
Content-Type: application/json
非簡單請求之前通常會觸發瀏覽器傳送一個 OPTIONS
預檢請求,以確保伺服器允許該跨域請求。
因此 options 請求就是預檢請求
預檢請求(Preflight Request)的意義
一句話解釋:預檢請求是瀏覽器在執行某些跨域請求之前,先發送的一種特殊的 HTTP 請求。它的主要目的是確保安全性,這個安全性針對服務端和客戶端,服務端是防止惡意請求對伺服器造成潛在的風險,客戶端是保護使用者的安全和隱私
非簡單請求之前,預檢請求先來詢問伺服器能否跨個域,就像是去朋友家做客,先打個電話問是否方便
伺服器是否允許跨域請求:透過預檢請求,瀏覽器可以確認伺服器是否允許來自不同域名的請求。
允許的請求方法:預檢請求可以告訴瀏覽器,伺服器允許哪些 HTTP 方法(如
GET
、POST
、PUT
等)。允許的請求頭部:預檢請求可以告訴瀏覽器,伺服器允許哪些自定義的請求頭部。
跨域請求
跨域請求是指從一個域(如 http://example.com
)向另一個域(如 http://another-domain.com
)傳送的 HTTP 請求。無論請求是簡單請求還是非簡單請求,只要涉及到不同的域名、埠或協議,就屬於跨域請求。因此跨域是不分簡單請求和非簡單請求的
非簡單請求的跨域處理(預檢請求的工作流程)
傳送預檢請求
當瀏覽器檢測到一個非簡單請求時,會先發送一個 OPTIONS
請求到伺服器,詢問伺服器是否允許該實際請求。這個預檢請求包含以下資訊:
請求方法(如
PUT
、DELETE
等)請求頭部(如
Content-Type
、Authorization
等)
伺服器響應預檢請求
伺服器收到預檢請求後,需要返回一個響應,告訴瀏覽器它是否允許這個跨域請求。響應中包含以下資訊:
允許的來源(
Access-Control-Allow-Origin
)允許的方法(
Access-Control-Allow-Methods
)允許的頭部(
Access-Control-Allow-Headers
)
傳送實際請求
如果伺服器允許該請求,瀏覽器纔會繼續傳送實際的請求
伺服器響應實際請求
伺服器處理實際請求,並返回響應
即使是簡單請求,如果是跨域的,瀏覽器仍然會進行一些安全檢查,但不會發送預檢請求。
迴歸本文主題,回答之前你是否好奇明明預檢請求是爲了確保伺服器和使用者的安全,為何還要減少它?
options 請求過多帶來的問題
效能損耗:
OPTIONS
請求是額外的網路開銷。雖然通常不會帶來顯著的效能問題,但在高流量的應用中,大量的OPTIONS
請求可能會增加伺服器負擔和網路延遲。使用者體驗:雖然
OPTIONS
請求本身很快(通常是幾 ms ),但如果它們頻繁出現或處理緩慢,可能會間接影響使用者體驗。減少這些請求可以確保實際的業務請求更快地得到響應。伺服器負擔:每個
OPTIONS
請求都需要伺服器進行處理,並返回相應的 CORS 頭部。這可能會增加伺服器的負擔,尤其是在處理大量預檢請求時。最佳化這些請求有助於減少伺服器的計算和網路開銷。
如何減少 options 請求呢
儘量使用簡單請求
從根源上看,瀏覽器不會對符合條件的 簡單請求 發起 OPTIONS
預檢請求,因此去使用簡單請求
限制使用自定義頭部
爲了避免觸發 OPTIONS
請求,儘量避免在請求中使用自定義頭部。自定義頭部會使請求成為非簡單請求,從而觸發 OPTIONS
預檢請求。
使用
Content-Type
限制
如果你使用 POST
請求,可以透過限制 Content-Type
頭部來避免 OPTIONS
請求。允許的 Content-Type
包括:
application/x-www-form-urlencoded
multipart/form-data
text/plain
如果你使用其他型別的 Content-Type
,如 application/json
,則會觸發 OPTIONS
請求。
最佳化請求模式
儘量將請求方式設計得更簡潔,避免複雜的跨域場景。如果可能,將請求合併爲較少的 API 呼叫,減少跨域請求的次數。
伺服器端配置
雖然前端沒有直接控制 OPTIONS
請求,但在服務端,你可以透過最佳化 CORS 配置來處理 OPTIONS
請求。確保伺服器對預檢請求的響應快速且高效,以減少對前端效能的影響。
使用同域名資源
如果可以,儘量將前端和後端部署在同一域名下。這樣可以避免跨域請求,完全不需要 OPTIONS
請求。
總結
想要減少 options 請求數量,主要可以透過確保請求滿足簡單請求的條件來避免預檢請求,或者最佳化請求設計和頭部使用
面試官問這個問題想必大部分人都是懵逼狀態,因為你可能沒有想過二次請求帶來的問題,想要避免他就需要清楚 options 請求的發生條件