[JS] AJAX
TL;DR
介紹Axios、XMLHttpRequest、Fetch三種不同寫法的AJAX行為。
先說結語,建議直接使用Axios。
參考資料
相關連結
- XMLHttpRequest | MDN
- Fetch | MDN
- Axios | Axios Homepage
- Axios Github | Axios Github
XMLHttpRequest
XMLHttpRequest是JS原生的AJAX語法,範例如下:
function reqListener() {
console.log(this.responseText);
}
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", reqListener);
oReq.open("GET", "http://www.example.org/example.txt");
oReq.send();
在JS-Promise篇章也有介紹如何透過Promise來封裝:
function get(url) {
return new Promise((resolve, reject)=> {
// 定義 Http request
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function() {
if (req.status == 200) {
// 使用 resolve 回傳成功的結果,也可以在此直接轉換成 JSON 格式
resolve(JSON.parse(req.response));
} else {
// 使用 reject 自訂失敗的結果
reject(new Error(req))
}
};
req.send();
});
}
// 往後的 HTTP 直接就能透過 get 函式取得
get('https://jsonplaceholder.typicode.com/todos/1')
.then((res) => {
console.log(res);
})
.catch((res) => {
console.error(res)
})
Fetch
Fetch也是JS原生的 語法,範例如下:
fetch("http://example.com/movies.json")
.then(function (response) {
return response.json();
})
.then(function (myJson) {
console.log(myJson);
});
Axios
範例:
axios.get('/user/12345')
.then(function (response) {
console.log(response.data);
console.log(response.status);
console.log(response.statusText);
console.log(response.headers);
console.log(response.config);
});
如果今天使用的是get
方法,回傳的內容會包裝成一個物件放在response
內
並且可以使用response.屬性名稱
的方式去將內容取出
例如如果要取出狀態碼就要使用response.status
,如果要取出內容的話就會在response.data
非同步觀念
在使用fetch或是axios等AJAX請求的時候,是非同步的。代表JS會先繼續執行後面的程式碼,直到伺服器回傳值(以上述例子來說就是response接收到資訊)
以以下程式碼為例:
let ary=[];
axios.get('url')
.then(function(response){
console.log('資料有回傳了'); //1
ary=response.data;
renderData();
});
function renderData(){
console.log(ary); //2
...
}
console.log(ary); //3
在執行axios.get的時候,會先送出一個http request,但是裡面的function只是先被註冊起來而已,還沒有收到response,所以這時候會先繼續執行。
接著會註冊renderData這個function,因為並沒有呼叫,所以也是只有註冊起來而已,並不會執行裡面的console.log(ary) //2
接著繼續執行,這時候就會先印出console.log(ary) //3
但是因為這個時候,axios還沒有回傳資料,所以ary仍然是空陣列
最後程式執行的順序會是3>>1>>2
我們使用renderData
的方式去註冊一個函式,並且只有在response回傳資料之後,才會執行。這樣就可以確保ary內已經有我們所要的值
Axios Codepen範例
info
API為六角學院所提供,僅學習使用,如有不妥請告知