Access-Control-Allow-Origin 的正確玩法
前端發起的跨域請求需要適當地響應 Access-Control-Allow-Origin 頭。但是這個頭目前並不支持部分通配符,無法匹配某個域名下的子域。直接使用星號又可能帶來各種問題。更坑爹的是它還不支持設置多個值。那么如果一個后端程序用於多個域名的訪問該怎么辦呢?
很多時候一套后端的程序都對應了多個調用方,它們使用的的域名不同,scheme 可能也不同。所以 Access-Control-Allow-Origin 的值沒法寫死一個域名。如果直接暴力地將其設置為「*」,可能導致一些未被授權的域名也能請求到資源。而且當 Access-Control-Allow-Credentials 的值為 true 時會導致Access-Control-Allow-Origin 無法被設置為「*」。
正確的玩法應該是在后端程序中獲取從 HTTP 請求頭傳過來的 Origin 字段,然后在程序中驗證它的值是否合法,並且做出適當的響應。也就是說,可以不依賴前端的跨域限制,后端如果認為一個請求的 Origin 來自不正確的地方就直接毫不留情地 403 掉。其它情況如果沒有 Origin 或者 Origin 正確則將 Origin 的值原原本本地放入 Access-Control-Allow-Origin 中響應回去。
其實雖然這個問題可以完全通過后端解決,但我還是很費解規范中無法使用局部通配符,和無法配置多個值的設定。也許這么設計的目的就是希望后端直接 403,而不是讓瀏覽器來攔截吧(反正讓瀏覽器來攔截還需要額外的傳輸成本,有點浪費)?
