A: 預檢不過 …
B: … postman 沒問題啊
A: Ummm…瀏覽器不太一樣…
內文
- 關於跨域
- 同源政策
- 請求類型
- preflight
- 如何解決跨域
- 設置正確標頭
- 使用套件
關於跨域
瀏覽器基於安全性的考量
有所謂的同源政策
即以 Ajax 發送請求時 默認情況只有同域名下才能互相存取
若 port 不同, 子域名不同或協定不同 皆屬於跨域
一般來說跨域只發生在瀏覽器
用伺服器直接發 Request 是沒問題的 (除非 API 本身就有問題 XD)
所以跨域實際上要解決的問題是瀏覽器機制的問題
為了解決此問題 我們會需要先知道瀏覽器發送 Request 的機制
當在瀏覽器發送 Request 時
主要分兩種類型的請求:
- 簡單請求
- 複雜請求
簡單請求包含以下兩點要素
- 方法為
- GET
- POST
- HEAD
- 只含有簡單請求的標頭
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-type:
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
除了簡單請求
…就是複雜請求
而簡單請求與非簡單請求最大的差別就在於…!?
Preflight
如果是複雜請求的話
需要特別留意瀏覽器在正式請求前
會先發送一個 HTTP OPTIONS 的選項請求
當對應的標頭都正確無誤才會發送正式的 Request
這個行為被稱為 預檢
如何解決跨域
根據簡單請求與非簡單請求有不同處理方式
底下以 node express 來做示範
- 簡單請求跨域:
- API 設定 Access-Control-Allow-Origin 的跨域來源
1 | const express = require("express"); |
- 非簡單請求跨域:
- API 設定 Access-Control-Allow-Origin 的跨域來源
- 外加設定 OPTIONS 的端口
- 設定 “Access-Control-Allow-Origin”
- 設定 “Access-Control-Allow-Headers” (加上額外的 header)
1 | const express = require("express"); |
- 使用套件 cors (簡單請求與複雜請求都可以)
1 | const express = require("express"); |
本文作者: David Huang
本文地址: https://davidblog.github.io/2020/06/29/cors/