Back To Articles

NUK JavaScript #5:AJAX 撈取資料

🧑🏻‍💻 Huang, Yung-Hsiang 📅 October 1, 2019

Article Image

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

如何用 AJAX 撈取資料

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

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

此時資料還沒回傳

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

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

資料會回傳到 responseresponseText

xhr.send()

ReadyState

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

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

處理取得的資料

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

使用範例:

// JSON.parse(字串)

let b = JSON.parse(a)
console.log(b[0])

JSON.parse(xhr.responseText)
console.log(data[1].ZipName_)

Onload 非同步

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

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

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

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

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

console.log(xhr.responseText) // #1

xhr.onload = function () {
  console.log(1) // #4
  let data = JSON.parse(xhr.responseText)
  console.log(data[0].ZipName_) // #5
}

console.log(xhr.responseText) // #2
console.log(2) // #3

AJAX 題目練習

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

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

<!-- HTML -->

<h2>鼓山區有幾筆案件哩 :P</h2>
<p>總共有 <span class="total"></span> 筆案件</p>
// JavaScript

let xhr = new XMLHttpRequest()
xhr.open(
  'get',
  'https://soweb.kcg.gov.tw/open1999/ServiceRequestsQuery.asmx/ServiceRequestsQuery?startdate=&enddate='
)
xhr.send()

xhr.onload = function () {
  let data = JSON.parse(xhr.responseText)
  let dataLen = data.length
  let total = document.querySelector('.total')
  let totalNum = 0

  for (let i = 0; i < dataLen; i++) {
    if (data[i].ZipName_ == '鼓山區') {
      totalNum += 1
    }
  }

  total.innerHTML = totalNum
  console.log('鼓山區總共有' + totalNum + '筆案件')
}

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