iT邦幫忙

2021 iThome 鐵人賽

DAY 4
0
Modern Web

不只是串串API,新手前端30天系列 第 4

DAY04 - API串接常見問題 - CORS - 概念篇 (1)

記得我第一次正式的串接API的時候,踏著愉悅的心想說自己要成為一個真正的前端要來串接了~~~ 結果寫了對應的程式打API之後,資料沒有出來,還馬上在console裏收到一個紅紅的錯

這個問題通常因為放到正式環境又沒問題了,或者直接拍出大絕請後端開好開滿,把 Access-Control-Allow-Origin: *設定完成,幾乎就解決問題了~
沒錯,如果你只想30秒解決這個問題,告訴你一個快速的結論:
請後端工程師,在API的header加上這個設定屬性Access-Control-Allow-Origin: *

但只要這樣就夠了嗎?身為一個追根究底的工程師,我們應該知道為什麼會有這個問題吧!或是如果在本機開發遇到這個狀況該怎麼處理?或是知道之後才方便之後被面試問到的時候不會答不出來吧(?)

好啦,有這麼多理由該知道,那我們就開始吧!

從錯誤訊息出發

其實錯誤訊息裡就告訴你為什麼了

access to XMLHttpRequest at 連結A from origin 連結B has been blocked by CORS policy: response to preflight request doesn't pass access control check: No 'Access-control-allow-origin' header is present on the requested resource

當你要從連結B要request到連結A時,被CORS的政策擋下來了,冒號後面告訴你原因:因為preflight request沒有通過存取檢測,請檢查看看request的來源的header有沒有access-control-allow-origin。

實務上就是我的前台網站在 連結A 但需要透過API 連結B 時,前後台兩者網址不同來源,但前台要取得不同來源的資料時,若沒有做好相關的設定就會出現上面的錯誤

錯誤訊息好像每個字都看得懂,但CORS是什麼意思?又為什麼要有CORS? header要加的這個又是什麼呢?接下來讓我們繼續看下去~

Same Origin Policy (同源政策)

在開始CORS之前,我們需要先知道瀏覽器的Same Origin Policy(同源政策)。
瀏覽器基於安全性的考量,規定當你的網站要呼叫API時,需要是同一個來源。
如果是不同來源,瀏覽器依然會幫你發出request,但會把收到的response阻擋起來不給你的網站。

那什麼叫同一個來源呢?

同源(Same-Origin)? 跨來源(Cross-Origin)? 來源怎麼判定?

當兩個網址的 schema(protocol) + host + port 皆相同,就是同源(Same-Origin),只要有一者不同,就是跨來源(Cross-origin)

以下舉幾個範例:

來源1 來源2 結論
http://www.abc.com.tw https://www.abc.com.tw 跨來源,schema不同
http://www.abc.com.tw http://www.api.abc.com.tw 跨來源,host不相同
http://www.abc.com.tw:8080 http://www.abc.com.tw:4200 跨來源,port不相同
http://www.abc.com.tw/web:8080 http://www.abc.com.tw/api:8080 同源

了解了同源、跨來源後,你應該接下來馬上會想到... 怎麼可能我要打的API都是同一個來源呢?如果就是不同源該則麼辦?

所以我們需要CORS! 什麼是CORS?

CORS = 跨來源資源共用(Cross-Origin Resource Sharing (CORS))。

跨來源資源共用 : 發出request的來源不同,但需要共用資源

可以把API request想像成大樓裡的一個個部門辦公室,有各自的門禁卡。資訊部的人不能進到行銷部,因為他們是不同來源。那如果最近資訊部跟行銷部密切合作,希望可以讓資訊部的人直接進到行銷部怎麼辦?這時候瀏覽器就是這個開啟門禁卡權限的管理員,要開啟門禁權限的方法就是CORS

  • 這邊我們要注意一點,門禁權限是瀏覽器訂的,意思是如果今天管理員換人了,不是瀏覽器了,那部門之間的門禁就消失了,就不會有不同來源會被阻擋下來的問題(所以你有發現嗎
    我們用postman打API的時候,就不會看到CORS的問題,因為管理員是postman不是瀏覽器了!)

CORS的運作原理

簡單來說,要開啟不同來共享資源的方式就是:透過在API的response中加入新的http header讓瀏覽器透過這些資訊,來決定要不要放行這個response。

我們已經簡單的知道為什麼我們會遇到這個問題了,那要怎麼加上新的http header當作跨來源的通行證? 又詳細的運作原理是什麼呢?待明天揭曉~

參考資料


上一篇
DAY03 - 前端與後端的溝通起點 - API
下一篇
DAY05 - API串接常見問題 - CORS - 概念篇 (2)
系列文
不只是串串API,新手前端30天30

1 則留言

0
Mizok
iT邦新手 5 級 ‧ 2021-09-19 12:46:56

漲姿勢!

我要留言

立即登入留言