轉生第十五日,這章節將會來介紹原生的 AJAX 技術。
AJAX 全名是 「Asynchronous JavaScript and XML」,中文是「非同步 JavaScript 和 XML」,在早期開發網頁時,居多都是採用 From 表單傳送資料到 Server,但是傳送表單之後往往會重新請求一整個畫面,那因為現階段使用者體驗越來越重要,所以 AJAX 的技術就變得不可忽視,早期作法當你送出表單後,還必須跟 Server 重新請求新的畫面,變成你要等兩個動作,所以就會看到一整個空白畫面。
那使用 AJAX 呢?使用 AJAX 的好處就是我們僅透過 JavaScript 傳送資訊到 Server,然後畫面保留在當前上,所以也就不用在跟後端重新請求一次畫面,而導致出現畫面空白,那麼這樣子在使用者體驗與 Server 的負擔也都會有較好的狀況。
所以 AJAX 最大的優點就是可以在不更新使用者當前網頁畫面取得新資料 & 更新畫面,進而達到更好的使用者體驗。
雖然 AJAX 並不需要仰賴什麼外掛,只需要使用者允許 JavaScript 的運作即可,故如果你將 JavaScript 給關閉就會無法運行 AJAX 唷~
更詳細的 AJAX 介紹我推薦可以看維基百科。
現階段有非常多的 AJAX 套件,其中就我知道的就有 Axios 以及 jQuery 本身的 AJAX API,但是這些 API 都是屬於打包好的東西,所以這邊我們主要是去了解 AJAX 底層技術也就是 XMLHttpRequest()
,了解底層技術也可以幫助自己對於現在 AJAX 套件有加分唷。
首先原生 AJAX 是使用 XMLHttpRequest()
方法,使用方式必須透過 new
實例化該方法:
var xhr = new XMLHttpRequest();
接下就會使用 XMLHttpRequest()
中的一個方法,也就是 open()
開啟要傳送 & 取得資料的 RESTful API URL(看成伺服器資料取得或傳送的路徑就好),那 open()
撰寫方式就像這樣 ↓
第三個參數通常會預設為非同步,也就是 false
,非同步的意思就是「我不會等你請求完資料我才做其他動作」。
接下來就要告知是否要傳送資料,若不用只需要寫 xhr.send(null);
即可。
最後的關鍵在這裡,請求 AJAX 行為後如果你沒有使用 xhr.onload = function () {...}
那就會導致錯誤,進而無法正常取得 AJAX 資料,所以完整的 XHR AJAX 行為如下:
var xhr = new XMLHttpRequest();
xhr.open('get', url);
xhr.send(null);
xhr.onload = function () {
...
}
另外如果要確保 AJAX 行為是成功的,那就可以使用 xhr.status
來判斷伺服器狀態碼,通常是判斷 200:
var xhr = new XMLHttpRequest();
xhr.open('get', url);
xhr.send(null);
xhr.onload = function () {
if(xhr.status === 200) {
...
}
}
那麼以上就是 AJAX 的底層技術,但這是早期的做法,目前已經不堪用於現在的 web 技術,一個不小心可能就會進入 Callback Hell (回調地獄,後面會介紹),拿我個人撰寫 AJAX 會使用第三方套件如 Axios、jQuery ajax api,如果不使用套件的話,則會使用 HTML5 後來新增的 Fetch API,撰寫方式是這樣子:
fetch(url).then((respons) => {
return respons.json(); //取的資料後將資料傳給下一個 then
}).then((data) => {
...
}).catch((error) => { // 當初出現錯誤時跑 catch
console.log(error);
})
可以發現與原本的 XHR 做法簡潔簡潔許多,且可以閃躲 Callback Hell,但是 使用 Fetch API 需注意一個問題,也就是 Fetch API 不支援 Internet Explorer 11
最後這邊補充 jQuery AJAX 寫法提供參考比較:
$.ajax({
url: ajaxUrl,
type: 'GET'
}).done(function(response) {
console.log(response);
}).fail(function( xhr, status, errorThrown ) { // 取得失敗時執行的階段程式碼
console.log('出現錯誤,無法完成!');
console.log('Error: ' + errorThrown );
console.log('Status: ' + status );
console.dir(xhr);
}).always(function( xhr, status ) { // 不論成功或失敗都會執行的回調函式
console.log('要求已完成!');
})
下一篇的 RE:從零開始的學習 JS 生活-第十六日 將會介紹 Callback Hell。
本文同步發表於:https://hsiangfeng.github.io/javascript/20190930/317345641/