iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 10
0
自我挑戰組

這些日子我學到的JavaScript 系列 第 28

這些日子我學到的JavaScript:Day27- AJAX

  • 分享至 

  • twitterImage
  •  

什麼是 AJAX ?
AJAX 是 Asynchronous JavaScript and XML(非同步的 JavaScript 與 XML 技術)的縮寫,簡單說就是網頁不用重新整理,就能即時地透過瀏覽器去跟伺服器溝通,撈出資料。

伺服器對 AJAX 資料請求回應通常是以三種資料格式其中之一(HTML、XML、JSON),最常與 Javascript 做搭配就是 JSON。

XMLHttpRequest 物件 — 跨瀏覽器撈資料
使用 XHR 物件可以在自己網頁上讀取遠端的 JSON 資料,最常見的用途是在註冊頁面驗證「用戶名」及「信箱」是否被重複使用。

設變數(xhr)
儲存一個 XMLHttpRequest 物件以抓取別人的資料,該物件裡面有很多方法跟特性可以做應用,例如 onload / readyState 等。

var xhr = new XMLHttpRequest();
readyState 特性的數值用以判斷目前讀取資料的狀態。

0 - 已經產生一個 XMLHttpRequest,但是還沒連結要撈的資料,接著下 open() 語法來設定環境(有三個參數)
1 - 用了 open(),但是還沒傳資料
2 - 偵測到你有用 send()
3 - 資料 loading 中
4 - 你撈到資料了,數據已經接收到
下 open() 指令
xhr.open('格式', '讀取的網址', true);
第一個參數: 格式,讀取資料 (get) / 傳送資料到伺服器 (post)
第三個參數: 同步與非同步
接著 xhr 的 readyState 會等於 1,代表我們用了 open() 但還沒把資料傳送過去。

傳送資料
xhr.send();
如果只是要讀取資料,則 () 內要打 null (空值)。
此時 readyState = 2,代表偵測到有用 send()。
接下來,如果成功讀取到資料,則 XML 物件內的 responseText 特性會把撈到的資料紀錄進去,此時 readyState = 4,代表已經成功撈到資料。

參照:XMLHttpRequest — JavaScript 發送 HTTP 請求 (I)

AJAX 非同步請求
通過 XMLHttpRequest 生成的請求可以有兩種方式來獲取資料,非同步模式或同步模式。
XMLHttpRequest 物件的 open() 方法的第三個參數,true 代表非同步、false 代表同步,以下來介紹非同步及同步的意義。

非同步:可以同時進行多個任務,不需要等待上一個動作完成,就能讓程式碼繼續往下跑,等到請求資料完成才會執行回傳函式。總之,在執行請求的同時,瀏覽器可以正常的執行其他事務的處理。
同步:必須等到請求完成才會繼續往下執行程式碼。
為了避免阻塞頁面,一般而言都會使用非同步請求,然而非同步請求在下了 send() 指令後,還需要一些時間 load 資料,在還沒撈到資料的情況下,程式碼繼續往下跑,那要怎樣才能順利將資料印出來呢?

解決方法:使用 XMLHttpRequest 中的 onload 事件,該事件的意思是「當資料全部跑完以後,才會觸發此事件」。

xhr.onload = function(){
console.log(xhr.responseText);
//把抓到的資料物件化或陣列化,加以運用
var str = JSON.parse(xhr.responseText);
//選取 DOM,並渲染至網頁
document.querySelector('要插入資料的 DOM .class 名稱').textContent = str[陣列編號].陣列屬性;
}
HTTP 狀態碼
打開 chrome 開發者工具選擇 Network 頁籤,重整一下可以看到該網頁讀取資料的狀況,其中有一個 status 欄,裡面的數字就是 HTTP 狀態碼,代表網頁連線的狀態。

以下先介紹 2 個狀態碼,其餘的狀態碼及更詳細的介紹,可以閱讀保哥的文章。

200:資料正確回傳
404:資料讀取錯誤
因此,剛剛上面的 onload 事件所觸發的回傳函式,可以用 if 判斷式把 HTTP 連線狀態加入判斷。

xhr.onload= function(){
console.log(xhr.responseText);
if(xhr.status == 200){
var str = JSON.parse(xhr.responseText);
document.querySelector('要插入資料的 DOM .class 名稱').textContent = str[陣列編號].陣列屬性;
} else{
console.log('資料錯誤');
}
}


上一篇
這些日子我學到的JavaScript:Day26- BOM
下一篇
這些日子我學到的JavaScript:Day28- AJAX 2
系列文
這些日子我學到的JavaScript 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言