Sean's Blog

An image showing avatar

Hi, I'm Sean

這裡記錄我學習網站開發的筆記
歡迎交流 (ゝ∀・)b

LinkedInGitHub

NUK JavaScript #5:AJAX 撈取資料

這次要介紹如何用 AJAX 撈取資料。

如何用 AJAX 撈取資料

使用資料:Open1999 派工受理案件資料
資料網址:https://data.kcg.gov.tw/dataset/open1999

首先,建立一個 XMLHttpRequest,它可以傳送一個網路請求到對方伺服器去要資料,並準備取得 (get) 網址資料。

此時資料還沒回傳

1let xhr = new XMLHttpRequest();
2xhr.open(
3  'get',
4  'https://soweb.kcg.gov.tw/open1999/ServiceRequestsQuery.asmx/ServiceRequestsQuery?startdate=&enddate='
5);

待對方的伺服器確認我們的身分後,會回傳資料給我們,拿到資料後再看要怎麼處理。

資料會回傳到 responseresponseText

1xhr.send();

ReadyState

撈取資料時,會出現以下幾種狀態,不同 readyState 代表不同的意思:

  • 0:已經新增一個 XMLHttpRequest,但是還沒連結到要撈的資料
  • 1:已發出網路請求,準備取得網址資料,但是對方還沒傳資料
  • 2:偵測到你有用 send()
  • 3:資料 Loading 中
  • 4:已接收到資料,資料會回傳到 response 跟 responseText

處理取得的資料

撈到 JSON 資料後,我們要先將字串轉型成 JSON 格式,使用 JSON.parse() 方法。

使用範例:

1// JSON.parse(字串)
2
3let b = JSON.parse(a);
4console.log(b[0]);
5
6JSON.parse(xhr.responseText);
7console.log(data[1].ZipName_);

Onload 非同步

如果用 VSCode 在練習的話,可能會發現資料都跑不出來?
但是在瀏覽器的 Console 上面卻可以跑出資料,為什麼會這樣子呢?

原因是 XHR 被放在等待區,此時資料還沒回傳。
但是程式碼編譯很快,所以馬上執行的話,撈出來的資料還是空值。

這邊可以加上 onload 語法解決這個問題,讓 XHR 裡面的程式碼 等到資料回傳時才會觸發

1xhr.onload = function () {
2  let data = JSON.parse(xhr.responseText);
3  console.log(data[1].ZipName_);
4};

以下程式碼中,加上 onload 之後 XHR 裡面的程式碼不會立刻執行,可以用 console.log 查看執行狀況。
前兩個 console.log(xhr.responseText) 回傳的都是空值,而且會等到最後資料回傳時才會觸發 onload 裡面的程式碼。

1console.log(xhr.responseText); // #1
2
3xhr.onload = function () {
4  console.log(1); // #4
5  let data = JSON.parse(xhr.responseText);
6  console.log(data[0].ZipName_); // #5
7};
8
9console.log(xhr.responseText); // #2
10console.log(2); // #3

AJAX 題目練習

題目:撈出鼓山區總共有多少案件

1999 API:https://data.kcg.gov.tw/dataset/open1999

1<!-- HTML -->
2
3<h2>鼓山區有幾筆案件哩 :P</h2>
4<p>總共有 <span class="total"></span> 筆案件</p>
1// JavaScript
2
3let xhr = new XMLHttpRequest();
4xhr.open(
5  'get',
6  'https://soweb.kcg.gov.tw/open1999/ServiceRequestsQuery.asmx/ServiceRequestsQuery?startdate=&enddate='
7);
8xhr.send();
9
10xhr.onload = function () {
11  let data = JSON.parse(xhr.responseText);
12  let dataLen = data.length;
13  let total = document.querySelector('.total');
14  let totalNum = 0;
15
16  for (let i = 0; i < dataLen; i++) {
17    if (data[i].ZipName_ == '鼓山區') {
18      totalNum += 1;
19    }
20  }
21
22  total.innerHTML = totalNum;
23  console.log('鼓山區總共有' + totalNum + '筆案件');
24};

以上資源是我自己整理過後的筆記,若有錯誤歡迎隨時和我聯繫