前言
在工作中遇到了幾次 CORS 的問題,通常前後端是不同人開發,因此在溝通上也許會有落差,較難察覺問題,因此將遇到的問題記錄下來。
Access-Control-Allow-Origin: *
說到支援跨網域呼叫,最容易查到的解法就是要允許特定來源(origin),這邊以星號(*)代表允許所有來源,如此一來任何網域的 api 連接到伺服器時,都會預設允許該跨網域呼叫。
然而,有時候添加了該 Header,卻仍然不行;
不行的原因容易被人忽略,因此以下詳細解說
OPTIONS
我們可以在 MDN docs 中讀到,在 GET 以外的方法,瀏覽器必須先傳送 OPTIONS 確認伺服器支援。
並且文中有提到「簡單請求」(Simple Request),在滿足特定條件下的簡單請求,該請求並不會發送 OPTIONS。
因此我們會發現,假如使用了 XMLHttpRequest Post JSON,瀏覽器便會發送 OPTIONS 請求,此時前端工程師使用 chrome 開發者工具,就可以看到 API 請求失敗。
這時候問題來了:
- 假設前端工程師沒有仔細檢查該請求是 OPTIONS
- 假設後端工程師沒有仔細檢查 Log 該請求是 OPTIONS
- 前端工程師表示 跨域請求異常
- 後端工程師表示 Header 已經加上 Access-Control-Allow-Origin
- 後端工程師表示 其他的 GET 請求都可以了啊
這時候問題就卡在這了,因此,請記得請求後端工程師允許 OPTIONS 請求。
jQuery ajax CORS
上述的情形,主要在闡述跨域請求時,XMLHttpRequest Post JSON發生的問題。
然而,曾經遇到後端工程師以 jQuery ajax 測試跨域 Post API,並不會先發送 OPTIONS 請求,順利呼叫!
也曾經遇到工程師以 XMLHttpRequest Post FormData,並不會先發送 OPTIONS 請求,順利呼叫!
因此找不出問題。
有興趣的朋友可以參考以下程式,在伺服器不允許 OPTIONS 方法時,XMLHttpRequest Post Json 會回報錯誤,而XMLHttpRequest Post FormData,或 jQuery v1.10.2 ajax 不會發送 OPTIONS。
(記得請將網址改成自己的測試伺服器)
更進一步的資訊,請參考上面提到的 MDN docs 連結。