前端基礎
-前端必學 - 甚麼是 API?前端如何串接 API?
this.web
對於剛接觸的新手來說,API 是一個蠻難懂的概念。但其實它觀念蠻簡單的,前端在獲取資料時,API 通常是一個網址,前端可以透過這個網址來獲取後端送來的資料。
舉個例子,假設你現在在蝦皮買了一件衣服,要到超商取貨,超商就是一個 API。
在這個例子我們可以看三個部分,"你" 到 "超商" 取 "店家發來的貨":
- 你: 前端
- 超商: API
- 發貨的店家: 後端、伺服器
換句話說,後端會發送資料到 API,前端可以利用 API 來獲取後端送過來的資料,這就是串接 API。
所以 API 就像一個可以取得各種資料的窗口。
有了基本概念之後,我們就可以來更深入的看看 API
甚麼是 API?
API 的全名是 「應用程式介面 Application Programming Interface」。
它允許不同的應用程式之間,以規範好的方式進行溝通和互動,即使他們是用不同的語言。就比如前端和後端可以利用 API 來溝通、傳資料。
而規範的方式是可以自訂的,比如後端可以決定前端要傳什麼參數才能取得特定的資料。
為甚麼要使用 API?
有了 API 可以大大降低開發人員的負擔,用很常見的例子來說,大部分的電商網站都提供線上刷卡付款,正是因為他們串接了金流公司提供的 API,這樣他們就不需要自行開發一個結帳系統。
在舉一個例子,我們在寫 JS 時的 setInterval
、setTimeout
等都是瀏覽器提供的 API,只要我們遵循它的使用方法,就可以很方便的計時,而不用自己寫一個計時功能的函數,這也是一種 API。
還有最近很流行的 open AI 也有提供 API,讓開發人員可以在自己的應用程式開發想要的 AI 功能,例如客服聊天機器人。
所以說,API 的好處有:
- 促進程式整合:API 允許不同的程式或服務彼此溝通和互動。這使得系統間的整合變得更容易。就像前面說的購物支付系統。
- 提高效率和速度:透過使用 API,你可以利用現有的功能和資源,而不需要重新發明輪子。這樣可以節省開發時間和成本。
- 擴充功能和彈性:你可以利用其他系統的 API,將它們的功能放到你的應用程式中,就像前面說的 AI 機器人。
前端如何串 API
前端串 API 的方式有很多,也有很多函式庫是在幫開發者更好的串 API,今天就帶你了解原生 JS 的兩種串 API 的方式,分別為:
- 傳統古老的 AJAX
- 後來更新的 Fetch
用傳統的 AJAX 串接 API
相信很多前端新手再找教學的時候,很常看到 AJAX 這個名詞,其實 AJAX 就是串接 API 的其中一種方法。
在正式進入 AJAX 之前,我想先來講講 AJAX 是什麼。在以前沒有 ajax 技術時,若要獲得資料或是傳送資料給後端,網頁需要向後端發送請求,然後等待後端回應,回應後需要重新載入整個頁面來完成資料的傳遞,這對於用戶體驗很不好。
而有了 ajax,我們就不需要重新載入整個頁面,因為他用到了非同步的概念,將請求和回應的部分交給瀏覽器去非同步處理,JS 只負責響應結束後,執行指定的回調函數,所以在很多地方都能大大提升用戶的體驗。
所以 AJAX 是什麼
ajax 是一個技術,全名叫做 Asynchronous JavaScript and XML,直接翻譯就叫做 "非同步的 JS 和 XML"。
XML 是一種用來儲存資料的標記語言,和 JSON 的功能類似,只不過現在更常使用 JSON 格式來儲存資料。因為和 XML 相比,JSON 更簡潔和易於讀寫。
使用 AJAX 串接 API
在 JS 中有提供一個內建的 XMLHttpRequest 物件來時做 ajax,使用方式如下
// 建立 XMLHttpRequest 物件
const xhr = new XMLHttpRequest();
// 監聽是否有回傳資料
xhr.addEventListener('readystatechange', () => {
if (xhr.readyState === 4 && xhr.status === 200) {
// 請求完成且成功
const response = xhr.responseText;
// 處理伺服器的響應
console.log(response);
}
});
// 用 open() 設置發送請求的方法
xhr.open('GET', 'http://example.com/api/data', true);
// 用 send() 發送請求
xhr.send();
readyState 代表目前的請求狀態,分成四種
- 0: 還沒開始
- 1: 讀取中
- 2: 已讀取
- 3: 資訊交換中
- 4: 完成
而 xhr.status
是 HTTP 的狀態碼,200
是成功的意思,常用的還有:
常用的 HTTP 狀態碼參考:
1xx 訊息回應
- 100 Continue:客戶端應繼續其請求
2xx 成功
- 200 OK:請求成功,常用於 GET 和 POST 請求
- 201 Created:請求已經被實現,而且有一個新的資源已經依據請求的需要而建立
- 204 No Content:伺服器成功處理了請求,但沒有返回任何內容
3xx 重新導向
- 301 Moved Permanently:請求的網頁已永久移動到新位置
- 302 Found:請求的網頁臨時重新導向到另一個位置
- 304 Not Modified:自從上次請求後,請求的網頁未修改過
4xx 客戶端錯誤
- 400 Bad Request:伺服器無法理解請求的格式,客戶端不應該嘗試再次使用相同的內容進行請求
- 401 Unauthorized:請求未經授權,這通常是因為未提供認證信息或認證失敗
- 403 Forbidden:伺服器拒絕請求
- 404 Not Found:伺服器找不到請求的網頁
- 408 Request Timeout:請求超時,伺服器等候請求時發生超時
5xx 伺服器錯誤
- 500 Internal Server Error:伺服器遇到了一個未知的錯誤,無法完成客戶端的請求
- 501 Not Implemented:伺服器不支持請求的功能,無法完成請求
- 503 Service Unavailable:伺服器目前無法使用(由於超載或停機維護)。通常,這只是暫時狀態
AJAX 實戰
接著我們可以利用網路上提供的免費 api 來練習。JSONplaceholder 就是其中一個免費的 api,他提供各種假資料讓我們免費串接和練習。我們今天就用它其中的一個 api 練習 👇,這是我們要用的 api 位置:https://jsonplaceholder.typicode.com/posts/1
💡還記得開頭提到的,對於前端串接資料來說,API 通常會是一個網址。
HTML<h1 class="title"></h1>
<p class="content"></p>
JavScriptconst title = document.querySelector('.title');
const content = document.querySelector('.content');
// 建立 XMLHttpRequest 物件
const xhr = new XMLHttpRequest();
// 監聽是否有回傳資料
xhr.addEventListener('readystatechange', () => {
if (xhr.readyState === 4 && xhr.status === 200) {
// 請求完成且成功
const response = xhr.responseText;
// 將回傳的資料轉換成可以使用的 JS 物件
const json = JSON.parse(response);
// 將獲得的 title 和 body 給頁面
title.innerText = json.title;
content.innerText = json.body;
}
});
// 用 open() 設置發送請求的方法
xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/1', true);
// 用 send() 發送請求
xhr.send();
成果 👇
使用 Fetch 串接 API
從上面就可以發現 XMLHttpRequest 的寫法非常複雜,而且若是有錯誤發生要處理,也非常麻煩,我們可能要寫很多 if-else
來判斷是哪裡錯誤,所以不管是 JQuery 還是 ES5 之後新增的 fetch 都是重新封裝 XMLHttpRequest 來讓其寫法更簡潔,接著來介紹更好用的 fetch 吧!
如果是新手的話,建議大概了解 XMLHttpRequest 就好,開發已經很少使用 XMLHttpRequest 了,更常使用 Fetch 或其他函式庫。
Fetch 的基本使用
Fetch 的語法非常簡單。
fetch(url, [options])
.then((res) => console.log(res))
- url: 後端提供的接口位置
- options: 可選,串 api 時的一些設定,如果沒有設定 options,fetch 就會自動以 get 的方式取得資料。
Fetch 實戰
我們一樣來用 JSONplaceholder 提供的網址來實戰練習看看~
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then((response) => console.log(response));
Fetch 會回傳一個 Promise,所以我們可以用 .then()
來取得資料,而 response 通常代表是後端回傳的結果。而這是他回傳的結果👇
這是它回傳回來的資料,我們先不用全部看懂,只要先知道真正的資料在 body 裡面,不過 body 為甚麼寫 ReadableStream 呢?
是因為 Fetch 為了更好的效能,它不會一次讀取全部的數據才回傳,而是逐塊讀取數據,然後存在 ReadableStream 裡面,所以我們需要用某些方法將資料解析出來。
最常使用的方式是 response.json()
,它會將資料自動解析成 json 格式,json 就像 js 的物件,所以解析成 json 後,我們就可以像操作 JavaScript 物件一樣獲取數據。
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then((response) => response.json())
.then((json) => console.log(json));
/*
{
"body" : "quia et suscipit...",
"id" : 1,
"title" : "sunt aut ...",
"userId" : 1
}
*/
可以看到他回傳的是一篇假文章,此時我們就可以像這樣去獲取文章的內容和標題。
const title = document.querySelector('.title');
const body = document.querySelector('.body')
fetch('https://jsonplaceholder.typicode.com/posts/1')
.then((response) => response.json())
.then((json) => {
title.innerText = json.title;
body.innerText = json.body;
});
你就可以看到和用 AJAX 一樣的結果了!
在 Fetch 中帶入參數
有時候我們會要傳入一些參數來獲取特定的資料,例如我們想取得 id = 2
的文章,可以用 new URLSearchParams()
搭配 template string
使用,例如:
function getData(id) {
fetch(
`https://jsonplaceholder.typicode.com/posts?${new URLSearchParams({
id: id
})}`
)
.then((response) => response.json())
.then((json) => console.log(json));
}
getData(2);
new URLSearchParams()
可以將物件轉換成 url 的查詢參數(param),舉例來說:
const params = { name: 'Jack', age: 25 };
const searchParams = new URLSearchParams(params);
console.log(searchParams.toString());
// name=Jack&age=25
Fetch 的常用選項
除了像上面那樣用 get
來取得資料,fetch 還提供第二個參數可以調整一些參數,例如將 method 改為 post
。
post
可以將前端的資料回傳給伺服器,我們一樣可以用 JSONplaceholder 來練習 post。
fetch('https://jsonplaceholder.typicode.com/posts', {
method: 'POST',
body: JSON.stringify({
title: 'fetch 教學',
body: '這是有關 fetch 的一篇教學',
author: 'this.web',
userId: 1,
}),
headers: {
'Content-type': 'application/json',
},
})
.then((response) => response.json())
.then((json) => console.log(json)); // 檢查資料是否有回傳
/* 通常會回傳你傳的資料,以下
{
title: 'fetch 教學'
body: '這是有關 fetch 的一篇教學',
author: 'this.web',
userId: 1,
...
}
*/
讓我來一一解釋上面的選項:
- method: api 請求的方法,例如 GET、POST、PUT、DELETE 等
- body: 傳送的資料主體
- headers: 請求頭,放一些有關於請求的相關訊息,像這裡的
'Content-type': 'application/json'
是指定伺服器回傳的資料為 json 格式
常見的 API 請求的方法:
- GET
- 用於從伺服器獲取資源的詳細資料
- 請求參數 (param) 通常包含在 URL 中
- POST
- 用於在伺服器上建立新資源
- 請求參數 (param) 包含在請求體 (request) 中
- PUT
- 用於更新伺服器上的現有資源
- PATCH
- 用於部分更新現有資源
- 請求體 (request) 只包含需要更新的欄位
- DELETE
- 用於從伺服器刪除指定的資源
我們 post 資料給伺服器後,它會回傳一些資料讓我們判斷我們是否有 post 成功,所以最後可以用 .then(console.log(json))
來檢查。
Fetch 傳接 API 的錯誤處理
有時候我們不會那麼順利,可能在串接 API 時發生一些預料外的錯誤,但發生錯誤時,fetch 不會自動發現,需要我們手動的去判斷,這也是 fetch 的小缺點。
通常可以用 response.ok
來判斷是否有成功,我們故意把網址打錯來試試看 (/posts 打錯成 /post)。
const post = fetch('https://jsonplaceholder.typicode.com/post/100')
.then((response) => {
if (!response.ok) {
throw new Error(response.status)
}
return response.json();
})
.then((json) => console.log(json))
.catch((error) => console.log(error))
// Error: 404
可以發現 catch
回傳一個 404,相信 404 大家都不陌生,代表網址錯誤 (請求的資源不存在),它是很常見的 HTTP code,而每個 HTTP code 都有各自的意思,可以參看前面我放的 HTTP Status code。
更詳細的 Fetch 用法可以參考 MDN。
小結
最後總結一下,可以把 API 想像成一個提供特定服務的窗口,這些窗口都會有各自的規範,只要遵循這些規範,就可以使用它們提供的東西。
並且介紹了 AJAX 和 Fetch,也有提到 Promise,其實 API、Promise、asnyc/await 這幾個東西經常是一起出現的,對於前端新手來說可能需要一點時間來理解,如果有任何問題都可以傳 email 或直接私訊我的 IG 來問我~!
那今天就這樣,希望能讓你了解何謂 API,並知道前端要怎麼 API,老樣子,我們下篇貼文見~!
相關系列文章