# [取得API的3種寫法XMLHttpRequest ajax Axios (筆記)] ###### tags: `XMLHttpRequest ajax Axios` ## XMLHttpRequest ### 使用HTTP請求獲取資料: ``` let request = new XMLHttpRequest() // 在.js檔案中,創造一個「XMLHttpRequest」物件,並指派給request變數。 request.open('GET', 'https://ghibliapi.herokuapp.com/films') // 使用open()函式連接,必要的參數包含「請求方法(‘GET’)」及「API端點的URL」 request.onload = function () { // 請求完畢後,我們就有權限進使用onload()函式,進到資料中 } } request.send() // send()正式送出請求 ``` ### .open('請求方法','url', true/false) ==true 非同步(預設值)==:程式碼不會等資料回傳回來就會繼續執行後續程式碼 false 同步:等資料處理(回傳/接收)完畢才繼續往下執行後續程式碼 預設使用非同步的原因:若資料量大時等全部載完才執行後續動作UX很糟(卡在那) ### 處理HTTP回傳資料: ``` // 回傳值為JSON格式,使用JSON.parse()將JSON轉換為javascript物件 var data = JSON.parse(this.response) //接下來就可以對資料做處理了。例:這裡的資料為陣列,所以下方用forEach()一一讀取陣列中的物件,並且印出每個物件的title data.forEach(movie => { // Log each movie's title console.log(movie.title) }) ``` ### 處理錯誤error: ``` // 將接回的資料存到變數data var data = JSON.parse(this.response) //判斷request.status,常見的錯誤為404(Not found),成功為200(OK),如果成功就執行印出資料,否則就印出error if (request.status >= 200 && request.status < 400) { data.forEach(movie => { console.log(movie.title)//成功 }) } else { console.log('error')//失敗 } ``` ### ==JSON.parse== JSON格式資料型態是(陣列包物件) ==資料傳輸時會被轉換成string(字串) 使用JSON.parse將資料轉換回原本的格式(陣列包物件)== --- ## Ajax有安全性問題 ### 引入jQuery CDN: ``` <script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script> ``` ### Ajax寫法 ```javascript= // 先把API的URL存成一個變數 var dataUrl= "https://cloud.culture.tw/frontsite/trans/SearchShowAction.do?method=doFindTypeJ&category=6" $.ajax({ url: dataUrl,// 指定API 的 URL 變數 method: 'GET',// 指定請求方法 dataType: 'json',// API的格式 data: '',//若有傳送資料時的資料設定 (GET沒有) async: true, // 預設是true=非同步,false=同步 (true時整行可省略) success: res =>{ console.log(res)// 成功的話執行... }, error: err =>{ console.log(err) // 失敗的話執行... }, }); // 箭頭涵式寫法:success: res =>{ ....} // 原始一般寫法:success: function(res){ ....} ``` ```javascript= $.ajax({ method: "POST",// 指定請求方法 url: "some.php",// 指定API 的 URL data: { name: "John", location: "Boston" },//若有傳送資料時的資料設定 (GET沒有) dataType: "json"// API的格式 async: true, // 預設是true=非同步,false=同步 (true時整行可省略) })//如果 post 成功的話處理回傳資料方式 .done(function( msg ) { alert( "Data Saved: " + msg ); }) //post 成功時回傳的訊息 .fail(function() { alert( "error" ); })//post 失敗時回傳的訊息 .always(function() { alert( "complete" ); });//一次程序完成時執行 ``` --- ## Axios 脫離jQuery之後會需要另外一個處理非同步的工具就是axios ### 引入Axios CDN: `<script src="https://unpkg.com/axios/dist/axios.min.js"></script>` ### axios寫法 ### get ``` axios.get(url, { params: { ID: 12345 } }) .then(function (response) { console.log(response);//成功 }) .catch(function (error) { console.log(error);//失敗 }); ``` ``` var dataUrl= "https://cloud.culture.tw/frontsite/trans/SearchShowAction.do?method=doFindTypeJ&category=6" axios.get(dataUrl) .then( (res) => { console.log(res.data); }) .catch( (err) => { console.log(err); }); ``` ### post ``` axios({ method: 'post', url: url, data: { firstName: 'Fred', lastName: 'Flintstone' } }); ``` ```javascript= axios.post('url, { firstName: 'Fred', lastName: 'Flintstone' }) .then(function (response) { console.log(response);//成功 }) .catch(function (error) { console.log(error);//失敗 }); ``` ``` //GET axios.get('http://api/user') .then(res =>{ console.log(res); }).catch(err => { console.log(err); }) //POST axios.post('http://api/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(res => { console.log(response); }) .catch(err => { console.log(error); }); ``` [使用Axios你的API都怎麼管理?](https://medium.com/i-am-mike/%E4%BD%BF%E7%94%A8axios%E6%99%82%E4%BD%A0%E7%9A%84api%E9%83%BD%E6%80%8E%E9%BA%BC%E7%AE%A1%E7%90%86-557d88365619)