<style> .title { padding-top: 25px } img{ border: 5px solid } </style> ###### tags: `Node.js` `AJAX` [AJAX] axios === [TOC] ## 參考網址 - [axios全攻略](https://ykloveyxk.github.io/2017/02/25/axios%E5%85%A8%E6%94%BB%E7%95%A5/) <h2 class="title">axios 基本介紹</h2> - 特色 - 底層使用 XMLHttpRequest。 - 寫法較為精簡、直覺 - 前後端通吃,後端也可以用 axios 發送網路請求。 - 過程 - 用 `get` 方法取得網址的資料 `response` - 成功後觸發 `then` 裡面的函式 ```javascript= axios.get('/user/12345') .then(function (response) { console.log(response.data); console.log(response.status); console.log(response.statusText); console.log(response.headers); console.log(response.config); }); ``` > 來源:[axios - github](https://github.com/axios/axios#response-schema) <h2 class="title">axios 環境安裝</h2> - 安裝方式 - 來源:[axios - github](https://github.com/axios/axios) - axios 有許多種安裝方式,以下範例使用 CDN 安裝 - 載入順序 - 通常會先載入套件,再去載入自己的 JS 檔案 - 確認是否成功 - 方法一:透過瀏覽器開發人員工具 > Network,查看載入狀態。 > ![](https://i.imgur.com/DN05n7w.png) > <small>Network 中看到有載入 axios.min.js,狀態值為 200</small> - 方法二:在自己的 JS 檔案 `console.log(axios)` 看是否成功印出。 > ![](https://i.imgur.com/uOYgiyC.png) > <small>載入 axios.min.js 後使用 console.log(axios)</small> ```javascript= // Using jsDelivr CDN: <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> // Using unpkg CDN: <script src="https://unpkg.com/axios/dist/axios.min.js"></script> ``` <h2 class="title">axios 串接外部資料</h2> > 練習用的 json 連結:https://hexschool.github.io/ajaxHomework/data.json 使用 axios 的範例,替換成上面的練習用連結 ```javascript= axios.get('https://hexschool.github.io/ajaxHomework/data.json') .then(function (response) { console.log(response.data); console.log(response.status); console.log(response.statusText); console.log(response.headers); console.log(response.config); }); ``` - 過程說明 - 使用 `get` 方法,並在第一個參數帶入網址。 - 當伺服器成功回傳,會觸發 `then` 裡面的函式。 - 函式被註冊但不會執行,要等到資料回傳才會觸發, - 參數 response (接收回傳資料的參數) - `response`:伺服器回傳的資料。是整理過的物件,能用物件方式取得裡面的資料。 - `response.data`:JSON 格式的資料。裡面是我們請求的資料。 - `response.status`:狀態碼。確認是否成功回傳資料,並可依不同狀態碼進行介面上的調整。 > ![](https://i.imgur.com/PclN4zY.png) > <small>response接收到的回傳結果</small> <h2 class="title">axios 將外部資料寫入到網頁上</h2> :::info 先把回傳的資料存到一個變數上,然後選取 DOM 放資料。 ::: - HTML ```htmlembedded= <h1 class="title"></h1> ``` - JS ```javascript= axios.get('https://hexschool.github.io/ajaxHomework/data.json') .then(function (response) { let ary = response.data const title = document.querySelector(".title") title.textContent = ary[0].name }); ``` <h2 class="title">axios 非同步觀念</h2> <h3>非同步範例</h3> - 如果將`console.log(ary)`放在`.then()`中,會正常顯示結果 ```javascript= let ary = [] axios.get('https://hexschool.github.io/ajaxHomework/data.json') .then(function (response) { ary = response.data console.log(ary) // [{...}] }); ``` - 如果我們將程式碼改寫如下,`console.log(ary)`放在`.then()`外面 ```javascript= let ary = [] axios.get('https://hexschool.github.io/ajaxHomework/data.json') .then(function (response) { console.log("資料有回傳!") ary = response.data }); console.log(ary) ``` - 印出來的結果依序會是 ```= [] "資料有回傳!" ``` :::danger 這是因為**非同步**的關係。 ::: <h3 class="title">非同步說明</h3> 在上面的範例中,程式碼的執行順序: - 建立變數 `ary` ,並賦值為空陣列 `[]`。 - 執行到 `axios.get()` 時,向伺服器發出請求,並且等待伺服器回傳資料。 - 等待的過程中,因為還沒收到資料,所以 `then` 裡面的函式不會執行。 - 在這同時,為了避免使用者等太久,<strong>程式碼會繼續往下執行</strong>。 - 執行到 `console.log(ary)` 時,`.then()` 裡面的函式還沒執行, `ary` 自然還沒被重新賦值,因此仍然是空陣列。 - 接下來,當伺服器成功回傳資料,`.then()` 裡面的函式將被觸發,執行裡面的程式碼,印出 `console.log()` 裡面的訊息,並將 `ary` 重新賦值。 - 因此,當程式跑完再去`console`列印`ary`,將會得到正確的值 > ![](https://i.imgur.com/ksDTldf.png) <h3 class="title">為什麼要有非同步</h3> - 假設我們要請求的是容量很大的檔案,如果沒有非同步,網頁的載入會卡在這裡,網頁的內容跑不出來,導致使用者體驗不佳。 <h2 class="title">透過函式設計處理非同步</h2> :::info 如何確保非同步資料正確回傳後,會執行對應的程式。 ::: - 可以建立一個處理回傳資料的函式,<strong>當資料回傳之後才會觸發這個函式</strong>。 - 這樣就能確保無論何時收到資料,資料都能照我們想要的結果執行。 HTML ```htmlembedded= <h1 class="title"></h1> ``` JS ```javascript= let ary = [] axios.get('https://hexschool.github.io/ajaxHomework/data.json') .then(function (response) { console.log("Receive data!") // "Receive data!" ary = response.data renderData() }); function renderData(){ console.log(ary) // [{"name": "王小名"}] const title = document.querySelector(".title") title.textContent = ary[0].name } console.log(ary) // [] ``` > ![](https://i.imgur.com/0rDaR8E.png)