iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 20
2

前端的學習之路,有一天會需要動態的互動,需要與外面的資料產生連結,今天試試看練習用簡單的 GET方法接一個 open data吧

在前端學習過程,都是在自己的電腦中作業,用的資料都是已知的靜態資料。但在真正的實作中,前端與後端需要協作,必須能夠拿取後端資料再放到前端網頁相對應的位置上。我們可以透過 Ajax 串 API 取資料。

那麼接下來我們試試看串接一個公開資料,再慢慢補充當中會遇到的問題。首先我們到政府的公開資料中,找一個公開資料來練習。

https://ithelp.ithome.com.tw/upload/images/20181104/20111959fPiU8kDIVy.png

選取其中一個類別後,在畫面左欄下方可以選取資料類型,在此範例中我選擇有提供 json 檔的公開資料,以便後續利用 JS 操作。

https://ithelp.ithome.com.tw/upload/images/20181104/201119591age2DADwT.png

我選擇了展覽資訊,作爲這次實作的對象,點選 JSON 檔案,打開後,應該會看到如下畫面中的 JSON 格式資料。

https://ithelp.ithome.com.tw/upload/images/20181104/20111959OcrYJZlOcD.png

好,第一個問題:什麼是 JSON 格式資料?

JSON 格式資料

JSON 全名爲 JavaScript Object Notation,它以純文字的方式傳遞資訊,資料以整體以 [ ] 陣列方式包裹,每一個物件(也就是每一筆資料),以 { } 物件方式包裹,內容以 key-value 的方式撰寫。

我們拿其中一筆資料來看看:

{"version":"1.4","UID":"5a27b93a8e1d4c16b03c6616","title":"哇賽!碰─體感大冒險2.0特展","category":"6","showInfo":[{"time":"2018/01/01 09:00:00","location":"高雄市三民區九如一路720號","locationName":"國立科學工藝博物館","onSales":"Y","price":"體驗票+100;優惠票+230;學生票+240;全 票+270","latitude":"22.6414306","longitude":"120.3225512","endTime":"2018/12/31 17:00:00"}],"showUnit":"(中華民國)南藝創意工程股份有限公司","discountInfo":"洽詢電話:07-3800089","descriptionFilterHtml":"2016年12月13日再度推出「哇賽!碰-體感大冒險2.0」,延續本館落實「寓教於樂」展示目標,力行推廣科普教育理念,讓民眾能在博物館愉快氛圍中學習感受科學相關原理。\r\n   「科學」,並不是一項艱深難懂的議題,「科普」就是利用各種傳媒以淺顯易懂的方式,例如展示、新聞、藝文、電影、電視…等,將科學的技術、知識、思想和方法等廣泛傳播,因此博物館與教育之間,相輔相成,科學博物館傳遞「科普」新知,即是要把科技概念廣泛應用在生活中,而「科普」可運用「體驗式教育」,讓教育本身充滿趣味化,本館積極倡導「科學體驗,體驗科學」做中學的理念,藉以加深甚至內化民眾學習印象,更期進一步提升大眾的科學素養,\r\n   我們常聽到自由落體、重力加速度、離心力、作用力與反作用力、失重…等科學詞彙,但是否真的能夠清楚明白說出定義呢?本特展以「實驗」為展示設計理念,期許民眾秉持「嘗試與挑戰」的精神,親身感受科學所要傳達的意涵。","imageUrl":"","masterUnit":["國立科學工藝博物館"],"subUnit":[],"supportUnit":[],"otherUnit":[],"webSales":"","sourceWebPromote":"","comment":"展出日期:2016/12/13 ~ 2019/12/12","editModifyDate":"","sourceWebName":"全國藝文活動資訊系統","startDate":"2018/01/01","endDate":"2018/12/31","hitRate":0}

例如由 "title":"哇賽!碰─體感大冒險2.0特展" ,得知有一個 key 值爲 title, 它的 value 爲 哇賽!碰─體感大冒險2.0特展。

例如由 "showInfo":[{"time":"2018/01/01 09:00:00","location":"高雄市三民區九如一路720號","locationName":"國立科學工藝博物館","onSales":"Y","price":"體驗票+100;優惠票+230;學生票+240;全 票+270","latitude":"22.6414306","longitude":"120.3225512","endTime":"2018/12/31 17:00:00"}] ,得知有一個 key 值爲 showInfo ,它的 value爲一個陣列包裹著物件,爲陣列中的陣列,物件中再以 key-value 的方式撰寫。

擠在一起的 JSON 用肉眼不好看,我們可以利用線上編輯器,轉成整理後的樣子,就可以很輕易理解 JSON 檔裡面有那些資訊。例如:JSON Editor Online。畫面如下圖:

https://ithelp.ithome.com.tw/upload/images/20181104/20111959sAK4hW9B8H.png

接下來我們利用 Ajax 發送一個請求,向市政府拿取展覽資料。在這之前問題二來了,什麼是 Ajax?

何謂 Ajax ?

看一段 MDN 的解說:

非同步 JavaScript 及 XML(Asynchronous JavaScript and XML,AJAX) 並不能稱做是種「技術」,而是 2005 年時由 Jesse James Garrett 所發明的術語,描述一種使用數個既有技術的「新」方法。這些技術包括 HTML 或 XHTML、層疊樣式表、JavaScript、文件物件模型、XML、XSLT 以及最重要的 XMLHttpRequest 物件。
當這些技術被結合在 Ajax 模型中,Web 應用程式便能快速、即時更動介面及內容,不需要重新讀取整個網頁,讓程式更快回應使用者的操作。
雖然 X 在 Ajax 中代表 XML,但由於 JSON 的許多優點,如輕量以及其本身就是 JavaScript 的一部分等,讓現今 JSON 比起 XML 被更廣泛的使用。JSON 與 XML 兩者都被用來在 Ajax 模型中包裝資訊。

上述內容提到,Ajax 是既有技術的新方法,使用 Ajax 必須搭配既有的技術。尤其是最重要的 XMLHttpRequest 物件,它是我們在進行資料請求時,必須使用到的實體。我們必須利用它所提供的方法建立請求、發送請求、存取請求回傳的內容。

接著我們來試試看向市政府拿取展覽資料。這次的實作是簡單的取用一個公開資料,參考 4. 從假資料到真資料:Ajax 與 API 串接 影片教學,只需要下面的程式碼:

var openUrl= "https://cloud.culture.tw/frontsite/trans/SearchShowAction.do?method=doFindTypeJ&category=6";
var xhr = new XMLHttpRequest();
xhr.open('GET',openUrl,true);
xhr.send();
xhr.onreadystatechange = function(){
 if(this.readyState === 4 && this.status === 200){
 var data = JSON.parse(this.responseText);
 console.log(data);
 }
};

我們一句一句看…

var openUrl= "https://cloud.culture.tw/frontsite/trans/SearchShowAction.do?method=doFindTypeJ&category=6";

首先使用一個變數稱爲 apiUrl ,裡面放個剛剛打開展覽 JSON 檔時的 URL。

var xhr = new XMLHttpRequest();

接著建立了XMLHttpRequest 物件稱爲 xhr。利用這個物件的方法進行資料請求。

xhr.open('GET',openUrl,true);

接著開啓一個請求,這個方法有三個參數,分別爲

  1. 請求方法:從伺服器支援的方式中擇一,在此實作範例中,不需要傳送資料給對方,也不需要做額外的動作(例如刪除),所以選用簡單的 GET 請求。記得請求方法要以大寫撰寫。其他請求方法可以看官方文件。
  2. 請求對象的URL:也就是剛剛打開展覽 JSON 檔時的 URL。
  3. 請求作業是否不同步進行:預設爲 true,代表要以不同步方式執行。
xhr.send();

送出請求。此方法可帶參數,傳送給對方的資料。

xhr.onreadystatechange = function(){
 if(this.readyState === 4 && this.status === 200){
 var data = JSON.parse(this.responseText);
 console.log(data);
 }
};

onreadystatechange 表示當狀態改變時。我們當狀態改變時,給一個方法,當中有 if 判斷。readyState 代表目前狀態,0 代表還沒開始,1 代表讀取中,2 代表已讀取,3 代表資訊交換中,4 代表一切完成。status 代表 HTTP 狀態碼,200 表示 ok,在此我們希望完成時有下一步動作,所以判斷條件爲 this.readyState === 4 && this.status === 200 。

接著我們使用一個變數 data,存放取得的資料,responseText 返回在發送請求後從服務器接收的文本。我們利用 JSON.parse 解析數據,使數據成為JavaScript 對象。接著使用 console.log 把它顯示出來。展開物件來看看結果如下:

https://ithelp.ithome.com.tw/upload/images/20181104/20111959JIEUbB2oeF.png

成功拿取資料後,再視需求整理顯示至前端畫面就可以囉:)


上一篇
Day19 JS Scroll 實作學習
下一篇
Day21 實作一個簡單的 Todolist (上)
系列文
前端之 " wow~原來是這樣啊 "30

1 則留言

0
kaichi1216
iT邦新手 5 級 ‧ 2019-10-14 12:49:53

感謝大大 講得好詳細啊~

我要留言

立即登入留言