iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 11
6
Modern Web

《你的地圖會說話? WebGIS與JavaScript的情感交織》系列 第 11

request的方式? ajax & fetch & axios

本系列文章已出版實體書籍:
「你的地圖會說話?WebGIS 與 JavaScript 的情感交織」(博碩文化)
WebGIS啟蒙首選✖五家地圖API✖近百個程式範例✖實用簡易口訣✖學習難度分級✖補充ES6小知識

大家今天補班辛苦啦!/images/emoticon/emoticon02.gif
之後準備要來介紹環域查詢,查詢範圍內資料庫中各類資料。
話說,前端如何request呼叫API拿到後端及資料庫的資料呢?
相信大家都常常使用JQuery Ajax!但是總該跳脫出舒適圈去試試其他方式了。
今天使用的API為OpenData中國土測繪中心的單點坐標回傳行政區

就來簡單介紹前端呼叫API的幾種方式吧!

  • XMLHttpRequest

上古時期的原生物件,為JavaScript的原生寫法。早期由微軟實作了一個Outlook與mail Server溝通的介面,後來把它整合進IE5瀏覽器,成了最早的Ajax技術的起源,於2006年被列入W3C的標準中。

優點

  • JavaScript的原生物件,不需引入任何函式庫
  • XHR是以事件為基礎(event-based)的非同步設計。

缺點

  • 難以捕捉各階段的狀態
  • 寫法冗長不直覺,每次使用就要new一個XMLHttpRequest物件

範例


        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'https://api.nlsc.gov.tw/other/TownVillagePointQuery/120.698659/24.156250/4326', true);
        xhr.send();
        xhr.onreadystatechange = function () {
            var data;
            var parser = new DOMParser();

            if (this.readyState === 4 && this.status === 200) {
                data = parser.parseFromString(this.responseText, "application/xml");
                data = xml2json(data, '')
                console.log(JSON.parse(data));
            }
        };
        xhr.onload = function () {
            console.log('onload');
        };
        xhr.onerror = function () {
            console.log('error');
        };
  • JQuery Ajax

JQuery為JavaScript撰寫的函式庫,用於簡化HTML與JavaScript之間的操作。起源於2006年,橫行Web數十年,歷久不衰。JQuery改良過後的Ajax定義出完整的架構,改良XHR本身架構不清晰的問題,並且可以由多個callback函式捕捉每個狀態以及事件發生的先後順序。至今,仍有許多開發者為了使用JQuery Ajax而引入此函式庫。

優點

  • 基於原生的XHR物件開發,改良XHR本身架構不清晰的問題,取代原生XHR物件成為主流的AJAX語法結構
  • 語法使用上直觀
  • 可以在不同的狀態訂定多個回調函式

缺點

  • JQuery的整個項目太大,最新的3.5.1版本有281KB,min版也有88KB。
  • 跨網站的HTTP要求(cross-site HTTP request)與CORS(Cross-Origin Resource Sharing)不易實作。
  • 不易處理非文字類型的資料
  • 除錯不易

範例

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        $.ajax({
            type: 'get',
            url: 'https://api.nlsc.gov.tw/other/TownVillagePointQuery/120.698659/24.156250/4326',
            dataType: 'json',
            timeout: 600000,
            async: false,
            success: function () {
                //console.log(arguments);
            },
            error: function(){
                console.log(arguments);
            }
        }).done(function () {
            console.log(arguments);
        });

https://ithelp.ithome.com.tw/upload/images/20200926/201306040rLCVZexEO.jpg

  • fetch API

2014年被定義為HTML5的一部分,2015年各大瀏覽器開始實作。加入ES6 promise物件,於response後以then()來處理,直觀的設計並且不須引入函式庫,令許多開發者趨之若鶩!

優點

  • 使用ES6的Promise物件做回傳的處理
  • 可以搭配 async/await
  • 不須引入函式庫
  • 可以直接呼叫定義的Request物件
  • 可以用Headers物件設定表頭

缺點

  • 需要使用catch做錯誤的捕捉與處理
  • 伺服器有回應的情況下,都會回傳已實現的Promise物件,須自行判斷伺服器的回傳代碼(200、500、404等)
  • 回傳的ReadableStream物件,對應不同資料類型(json、blob、formdata)需要使用不同的對應方法。
  • IE不支援 (使用Fetch polyfill)

範例1

        const req = new Request('https://api.nlsc.gov.tw/other/TownVillagePointQuery/120.698659/24.156250/4326', { method: 'GET', cache: 'reload' })
        fetch(req).then((response) => {
            console.log(response);
        }).catch((err) => {
            console.log('錯誤:', err);
        })

https://ithelp.ithome.com.tw/upload/images/20200926/20130604PoEDum3jSf.jpg
範例2

        fetch('https://api.nlsc.gov.tw/other/TownVillagePointQuery/120.698659/24.156250/4326', {}).then((response) => {
            console.log(response);
            return response.text();
        }).then(responseText => {
            let parser = new DOMParser();
            return parser.parseFromString(responseText, "application/xml");

        }).then(xmlString => xml2json(xmlString, ''))
            .then(jsonData => console.log(JSON.parse(jsonData)))
            .catch((err) => {
                console.log('錯誤:', err);
            });

https://ithelp.ithome.com.tw/upload/images/20200926/20130604XsK4ORCLlO.jpg
↑ 這邊使用 xml2json.js 處理xml資料

  • axios

vue.js框架的作者尤雨溪推薦使用,操作類似JQuery,並且有別於JQ的厚重,為輕量化設計的函式庫。跟fetch一樣使用promise物件,卻不限於瀏覽器,在node.js中也能使用,成為開發者新的產品/專案的首選。

優點

  • 使用方法類似於jQuery
  • 可以搭配 async/await
  • 支持Promise
  • 可以在node.js中使用
  • 支援防CSRF
  • 輕量化,約13KB
  • 可以取消要求
  • 可以自動轉換JSON資料
  • 可以用 axios.create 方法做API domain的管理

缺點

  • 需要使用catch做錯誤的捕捉與處理

範例

<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.20.0/axios.js"></script>
     axios.get('https://api.nlsc.gov.tw/other/TownVillagePointQuery/120.698659/24.156250/4326')
            .then(function (response) {
                let data = response.data;
                console.log(arguments)
            })
            .catch(function (error) {
                console.log(error);
            })
            .finally(function () {
                console.log('finally');
            });

https://ithelp.ithome.com.tw/upload/images/20200926/20130604fflWqGylcT.jpg


今天簡單講了四種request的方法,
大家特別喜歡哪一種呢?
有沒有為fetch與axios的瑜亮情結而有感而發呢?

明天要來介紹如何用環域(Buffer),在地圖上畫圓並進行點資料的查詢。
(還在想要不要繼續用Here Maps API?還是大家想看Leaflet呢?)

猶豫不決的我。/images/emoticon/emoticon06.gif


上一篇
[番外篇] MSSQL Spatial 地理空間資訊查詢
下一篇
[5-1] 環域與繪圖工具 - 以Leaflet Draw實現
系列文
《你的地圖會說話? WebGIS與JavaScript的情感交織》30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言