學會游泳會好的方法就是掉進水裡
今天就直接來用react 取api
我直接參考React官網的教學:https://zh-hant.reactjs.org/docs/faq-ajax.html
來連到永豐的api:https://mma.sinopac.com/ws/share/rate/ws_exchange.ashx
原本我想直接用內建的fetch,不過找資料時看到有另一個選項:axios
網路上有很多fetch跟axios比較的文章
看起來是比fetch更優的選擇,所以改用axios
npm install axios
因為要抓永豐的api會遇到我在[Day 11] - 準備串接永豐匯率API!
提到的CORS問題,由於是不同網域、不同埠號,違反CORS規則而被瀏覽器禁止了接收資料。
所以我打算使用jsonp作法來繞過去
npm install axios-jsonp
先測試一下
axios({
url: 'https://mma.sinopac.com/ws/share/rate/ws_exchange.ashx',
method: 'get',
adapter: jsonpAdapter,
}).then((res) => {
console.log(res.data)
}).catch((error) => { console.error(error) });
打開瀏覽器看看結果
暈倒 原來過了CROS後還有CROB要解決
為了抄近路有時候反而繞了遠路
CORB (Cross-Origin Read Blocking)跟CORS類似,都是瀏覽器用來保護用戶的安全機制,
只要瀏覽器發現,要載入的內容的content type(例如:application/json)跟它被放置的標籤不一致(如<script>
是用來放javascript的標籤,如果<script>
內要被載入的資源的content type是json就會被阻擋)
查了很久都沒找到解決辦法...
但是永豐自己是怎麼做到的呢?
看了一次永豐網銀用來取得匯率的js方法,也沒看出什麼端倪
...
就在我快要放棄時,發現了藏在細節裡的魔鬼
重新看永豐的網銀取匯率時,會在api網址後加一些參數
看上圖可以發現,永豐的匯率api在url帶了一些參數後,content type就變成javascript了!
這不就是為了jsonp而生的設計嗎
稍微試一下,就可以試出,那個關鍵的參數就是Cross=genREMITResult
只要帶上這個參數,就能避過CROB了
馬上試一下:
錯誤發生的原因是我們從API得來的內容:
genREMITResult([{"TitleInfo":"報價時間:2021-10-08 15:30:23本資訊僅供參考,實際成交匯率以本行牌告交易當下所議定的匯率為準(牌告更新自營業時間9:00至15:30止)。","QueryDate":"2021/10/09 18:22:49","HeadInfo":[{"HeadText":"幣別","HeadAlign":"2","DataAlign":"1","MainShow":"Y","DetailShow":"N","FieldKey":"DataValue1","OrderIndex":"01","FieldWidth":"20"},{"HeadText":"銀行買進Bank Buy","HeadAlign":"2","DataAlign":"2","MainShow":"Y","DetailShow":"N","FieldKey":"DataValue2","OrderIndex":"02","FieldWidth":"10"},{"HeadText":"銀行賣出Bank Sell","HeadAlign":"2","DataAlign":"2","MainShow":"Y","DetailShow":"N","FieldKey":"DataValue3","OrderIndex":"03","FieldWidth":"10"},{"HeadText":"","HeadAlign":"2","DataAlign":"2","MainShow":"N","DetailShow":"N","FieldKey":"DataValue4","OrderIndex":"04","FieldWidth":"10"},{"HeadText":"","HeadAlign":"2","DataAlign":"2","MainShow":"N","DetailShow":"N","FieldKey":"DataValue1Img","OrderIndex":"05","FieldWidth":"10"}],"SubInfo":[{"DataValue1":"美元(USD)","DataValue1Img":"/mma8/mobile/images/Rate_Info/USD.png","DataValue2":"27.97800","DataValue3":"28.08200","DataValue4":"USD"},{"DataValue1":"日圓(JPY)","DataValue1Img":"/mma8/mobile/images/Rate_Info/JPY.png","DataValue2":"0.24860","DataValue3":"0.25200","DataValue4":"JPY"},{"DataValue1":"港幣(HKD)","DataValue1Img":"/mma8/mobile/images/Rate_Info/HKD.png","DataValue2":"3.57510","DataValue3":"3.62560","DataValue4":"HKD"},{"DataValue1":"歐元(EUR)","DataValue1Img":"/mma8/mobile/images/Rate_Info/EUR.png","DataValue2":"32.19000","DataValue3":"32.53600","DataValue4":"EUR"},{"DataValue1":"英鎊(GBP)","DataValue1Img":"/mma8/mobile/images/Rate_Info/GBP.png","DataValue2":"37.89700","DataValue3":"38.29300","DataValue4":"GBP"},{"DataValue1":"瑞士法郎(CHF)","DataValue1Img":"/mma8/mobile/images/Rate_Info/CHF.png","DataValue2":"30.02700","DataValue3":"30.23800","DataValue4":"CHF"},{"DataValue1":"澳幣(AUD)","DataValue1Img":"/mma8/mobile/images/Rate_Info/AUD.png","DataValue2":"20.32800","DataValue3":"20.55200","DataValue4":"AUD"},{"DataValue1":"新加坡幣(SGD)","DataValue1Img":"/mma8/mobile/images/Rate_Info/SGD.png","DataValue2":"20.52800","DataValue3":"20.72700","DataValue4":"SGD"},{"DataValue1":"瑞典幣(SEK)","DataValue1Img":"/mma8/mobile/images/Rate_Info/SEK.png","DataValue2":"3.15530","DataValue3":"3.21830","DataValue4":"SEK"},{"DataValue1":"加拿大幣(CAD)","DataValue1Img":"/mma8/mobile/images/Rate_Info/CAD.png","DataValue2":"22.22500","DataValue3":"22.43300","DataValue4":"CAD"},{"DataValue1":"泰銖(THB)","DataValue1Img":"/mma8/mobile/images/Rate_Info/THB.png","DataValue2":"0.81130","DataValue3":"0.84440","DataValue4":"THB"},{"DataValue1":"南非幣(ZAR)","DataValue1Img":"/mma8/mobile/images/Rate_Info/ZAR.png","DataValue2":"1.82920","DataValue3":"1.91410","DataValue4":"ZAR"},{"DataValue1":"紐西蘭幣(NZD)","DataValue1Img":"/mma8/mobile/images/Rate_Info/NZD.png","DataValue2":"19.27800","DataValue3":"19.49200","DataValue4":"NZD"},{"DataValue1":"澳門幣(MOP)","DataValue1Img":"/mma8/mobile/images/Rate_Info/MOP.png","DataValue2":"3.43410","DataValue3":"3.55860","DataValue4":"MOP"},{"DataValue1":"人民幣(CNY)","DataValue1Img":"/mma8/mobile/images/Rate_Info/CNY.png","DataValue2":"4.31890","DataValue3":"4.37390","DataValue4":"CNY"},{"DataValue1":"離岸人民幣(CNH)","DataValue1Img":"/mma8/mobile/images/Rate_Info/CNH.png","DataValue2":"4.31890","DataValue3":"4.37000","DataValue4":"CNH"}],"MemoUrl":null,"Header":"SUCCESS","Message":""}]);
被當作JS執行,因為永豐在JSON外還用了一個genREMITResult()方法包住
可是卻沒有定義這個方法的關係...
要怎麼解決,明天繼續研究...
前端的水也是挺深的