# [JavaScript] 使用老式xhr取得API資料 ###### tags: `JavaScript` ### 執行三步驟 1.取槍:產生一個XMLHttpRequest 2.上膛:取得要讀取的網址,get(讀取資料)、傳送資料到伺服器 3.擊發:傳送send 4.回膛:回傳資料到自己的瀏覽器 ``` var xhr = new XMLHttpRequest(); xhr.open('get','https://vince.project/data.json',ture) xhr.send(null); ``` ![](https://i.imgur.com/WICMBrs.png) ### 可透過console得知現行階層 readyState顯示的數字含義 0 - 產生XMLHttpRequest,但沒有連結要撈取的資料 1 - 使用Open(),未傳送資料 2 - 偵測到有send指令 3 - loading 4 - 完成取得資料 ![](https://i.imgur.com/B3Jo6dY.png) #### 步驟2上膛解析 xhr.open('get','https://vince.project/data.json',ture) true非同步:不會等資料傳回,就讓程式繼續往下跑,等到回傳才會自動回傳,如果載入的資料量入過大,不可能等到資料全部上傳後才顯示程式,因此仍會使用true。 false同步:等資料傳回來之後才會讓程式碼繼續往下跑 #### 解決方式:使用onload ![](https://i.imgur.com/jtJcnSv.png) ``` //使用onload事件,當確定資料有回傳之後,便會執行函數 xhr.onload = function(){ console.log(xhr.responseText) //顯示資料訊息 var str = JSON.parse(xhr.responseText); //將回傳資料傳到瀏覽器-字串轉陣列:JSON.parse() document.querySelector('.message') //HTML的文字訊息 class="message" .textContent = str[0].name //將要抓取的資料顯示於頁面 } ``` #### status狀態顯示 * 正確:200 * 錯誤:404 可使用判斷式當狀態正確才顯示於網頁 if(xhr.status ==200){顯示資料} else{資料錯誤} #### CORS 跨網域撈取資料 一般來說跨網域需要詢問對方有沒有開啟CORS,開啟才有辦法抓取資料,取得API也是相似,ex.高雄市公開json資料便沒有開啟此功能。 可使用偵測網址查閱狀態:http://test-cors.org/ ### Post寫法,登入介面資料串連(與後端串接) 依照後端工程師的作業方式post擇一使用 #### 第一種方式:Post 表單網址傳入 HTML語法 ![](https://i.imgur.com/ni1amYE.png) JS語法 ``` var xhr = new XMLHttpRequest(); xhr.open('post','https://hexschool-tutorial.herokuapp.com/api/signup',true); xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xhr.send('email=abcdexx@gmail.com&password=12345678'); ``` * 後端會提供open()網址與email帳密資料,逐步輸入即可 * 第三行setRequestHeader輸入傳入形式 * 注意匯入的email只能用一次,不行重複輸入 * 參考資料:https://github.com/hexschool/nodejs_ajax_tutorial #### 第二種方式:Post AJAX用JSON傳遞 ![](https://i.imgur.com/8dnOKqQ.png) * 在setRequestHeader使用application/json * account以物件的方式納入emal帳密 * 要將物件轉換成JSON格式,需使用stringify更改為“字串” ### 觀念解析(get & post) 1. 使用get向伺服器或者網址詢問回傳需求 ![](https://i.imgur.com/v0nxGH1.png) 2. content type 使用網址表單輸入格式 application/x-www-form-urlencoded ![](https://i.imgur.com/ODRtTVU.png) 3. content type 使用JSON application/json ![](https://i.imgur.com/vNC1a71.png) ## 實作執行 ![](https://i.imgur.com/o0ZGXNc.png) ``` var send = document.querySelector('.send'); send.addEventListener('click',signup,false); function signup(){ var emailStr = document.querySelector('.account').value; var passwordStr = document.querySelector('.password').value; var account = {}; account.email = emailStr; account.password = passwordStr; var xhr = new XMLHttpRequest(); xhr.open('post','https://hexschool-tutorial.herokuapp.com/api/signup',true); xhr.setRequestHeader('Content-type','application/json'); var data = JSON.stringify(account); xhr.send(data); xhr.onload = function(){ var callbackData = JSON.parse(xhr.responseText); console.log(callbackData); var veriStr = callbackData.message; if(veriStr =="帳號註冊成功"){ alert('帳號註冊成功!!'); }else{ alert("帳號註冊失敗!"); } } ``` * 使用click監聽事件send按鈕 * 定義帳號account及密碼的值 * 載入Post AJAX用JSON傳遞物件(物件需轉字串) * 使用onload事件以取得responseText * 最後以判斷式得出註冊成功與否