前面,我們知道為什麼會看到CORS的錯誤訊息,也簡單的知道如果我們要在瀏覽器上跨來源存取API資料,就要通行證,新的http header,那這個通行證是什麼呢?今天就讓我們看一下吧
其實要解決CORS的問題,正宗的解法,就是要請後端設置CORS header
後端要怎麼設定哪些通行證呢?根據不同的需求,需要不同的通行證,有哪些通行證呢?
http://web.com.tw
或 給 *
允許所有來源可以跨域存取。Access-Control-Allow-Origin: *
true
,預設為false
。另外,當此屬性設定為true時,Access-Control-Allow-Origin
則不能設定為*
Access-Control-Allow-Credentials:true
Access-Control-Allow-Methods:POST, GET, PUT, DELETE
Access-Control-Allow-Headers: Authorization
Access-Control-Allow-Methods
和 Access-Control-Allow-Headers
可以cache的秒數上限(單位:秒)。每一個瀏覽器會有預設的最大值 ,當 Access-Control-Max-Age 大於預設值時,會優先採用預設值。Access-Control-Max-Age: 600
// Cache results of a preflight request for 10 minutesAccess-Control-Expose-Headers:X-My-Custom-Header
-> 表示瀏覽器能夠存取response當中的 X-My-Custom-Header如果後端暫時找找不到人,前端可以用怎麼樣的方式暫時自救一下呢...
前面有說到,跨網域的限制是因為瀏覽器所以才會有的,
如果先透過非瀏覽器的方式取的API response,加上該給的header通行證,再傳回給前端,那是不是就沒問題了!而這種方式,就叫CORS Proxy。
原理架構如下:
Browser ↔ CORS Proxy Server ↔ API
透過CORS Proxy Server的模式繞過 瀏覽器的跨域限制, 進而實踐存取API Server的response
CORS Proxy可以自己架設,也可以使用第三方的CORS Proxy,其中很方便使用的就是cors-anywhere
了~
cors-anywhere的使用方式非常簡單,直接把 https://cors-anywhere.herokuapp.com/
加在你的API URL前就可以了,如以下的範例:
const corsURL = 'https://cors-anywhere.herokuapp.com/'; // use cors-anywhere to fetch api data
const apiURL = 'https://www.api.com/device'; // origin api url
// api call
axios
.get(`${corsURL}${apiURL}`, {
})
.then((response) => (console.log(response))) // 把结果集传到info这个数组
.catch((error) => {
console.warn(error);
});
可能會在console看到這個錯誤
可以切到network後,發現API顯示的錯誤是403
再切換到response會看到以下的訊息 "See /corsdemo for more info"
在字上點選右鍵,open in new tab
會帶你到cros-anywhere的聲明頁面,點選按鈕“request temporaty access to the demo server”
按完後底下會出現一行文字,告訴你現在已經可以暫時使用這個server了
回到原本存取API的頁面,再按一下重新整理,應該就可以順利看到囉
*不過cros-anywhere在太多的request下,也會限制使用次數,所以這只是一個暫時前端開發方式,還是要請後端大大把API的header加好,通行證權限開好開滿才是正途R~~
看到這裡有發現其實這個是後端需要設定好的項目嗎?但前端為什麼要知道?
這是因為這是前端在使用時才會遇到問題(瀏覽器的限制)。因此前端必須知道這個問題的原因之後,自己遇到這個問題的時候也才能很確定該怎麼處理喔(像我一開始遇到的時候因為搞不清楚狀況很想自己解決,搞了好久QQ),知道原理後也才能與後端討論或建議應該怎麼加才能正常使用喔~~
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age