Web API 簡介

首先,我們將從宏觀層面審視 API:它們是什麼,如何工作,如何在程式碼中使用它們,以及它們的結構是怎樣的?我們還將瞭解不同主要類別的 API 是什麼,以及它們有哪些用途。

預備知識 熟悉 HTMLCSSJavaScript,尤其是 JavaScript 物件基礎知識以及 DOM 指令碼網路請求等核心 API 知識。
學習成果
  • Web API 是什麼,以及它們能做什麼。
  • API 的使用方式。

API 是什麼?

應用程式程式設計介面(API)是程式語言中提供的構造,旨在讓開發人員更輕鬆地建立複雜功能。它們將更復雜的程式碼抽象出來,提供了更簡單的語法供您使用。

舉一個現實世界的例子,想想您家裡、公寓或其他住所的電力供應。如果您想在家裡使用電器,只需將其插入插座即可工作。您不會嘗試將其直接連線到電源——這樣做效率非常低,而且如果您不是電工,嘗試這樣做既困難又危險。

Two multi-plug holders are plugged into two different plug outlet sockets. Each multi-plug holder has a plug slot on it's top and to it's front side. Two plugs are plugged into each multi-plug holder.

圖片來源:過載的插座,由 The Clear Communication People 釋出在 Flickr 上。

同理,如果您想程式設計一些 3D 圖形,使用 JavaScript 或 Python 等高階語言編寫的 API 會容易得多,而不是嘗試直接編寫控制計算機 GPU 或其他圖形功能的低階程式碼(例如 C 或 C++)。

注意:另請參閱 API 詞彙表條目以獲取進一步說明。

客戶端 JavaScript 中的 API

尤其是客戶端 JavaScript,擁有許多可用的 API——它們不屬於 JavaScript 語言本身,而是構建在核心 JavaScript 語言之上,為您的 JavaScript 程式碼提供了額外的超能力。它們通常分為兩類:

  • 瀏覽器 API 內建在您的 Web 瀏覽器中,能夠公開來自瀏覽器及周圍計算機環境的資料,並用它做有用的複雜事情。例如,Web 音訊 API 提供了用於在瀏覽器中操作音訊的 JavaScript 構造——獲取音軌、改變其音量、應用效果等。在後臺,瀏覽器實際上正在使用一些複雜的低階程式碼(例如 C++ 或 Rust)來執行實際的音訊處理。但同樣,這種複雜性被 API 抽象掉了。
  • 第三方 API 預設不內建在瀏覽器中,您通常需要從 Web 上的某個地方檢索它們的程式碼和資訊。例如,Google Maps API 允許您在您的網站上顯示辦公室的互動式地圖。它提供了一組特殊的構造,您可以用來查詢 Google Maps 服務並返回特定資訊。

A screenshot of the browser with the home page of firefox browser open. There are APIs built into the browser by default. Third party APIs are not built into the browser by default. Their code and information has to be retrieved from somewhere on the web to utilize them.

JavaScript、API 和其他 JavaScript 工具之間的關係

上面我們討論了客戶端 JavaScript API 是什麼,以及它們與 JavaScript 語言的關係。讓我們回顧一下,使其更清晰,並提及其他 JavaScript 工具的適用位置:

  • JavaScript — 一種內置於瀏覽器的高階指令碼語言,允許您在網頁/應用程式中實現功能。請注意,JavaScript 也可在其他程式設計環境中使用,例如 Node
  • 瀏覽器 API — 內置於瀏覽器中,位於 JavaScript 語言之上,讓您更輕鬆地實現功能。
  • 第三方 API — 內置於第三方平臺(例如 Disqus、Facebook)中的構造,允許您在自己的網頁中使用這些平臺的一些功能(例如,在網頁上顯示您的 Disqus 評論)。
  • JavaScript 庫 — 通常是一個或多個 JavaScript 檔案,包含您可以附加到網頁的自定義函式,以加快或實現常見功能的編寫。示例包括 jQuery、Mootools 和 React。
  • JavaScript 框架 — 比庫更進一步,JavaScript 框架(例如 Angular 和 Ember)通常是 HTML、CSS、JavaScript 和其他技術的集合包,您安裝後可用於從頭開始編寫整個 Web 應用程式。庫和框架之間的關鍵區別在於“控制反轉”。呼叫庫中的方法時,開發人員擁有控制權。而使用框架時,控制權是反轉的:框架呼叫開發人員的程式碼。

API 能做什麼?

現代瀏覽器中有大量的 API 可用,允許您在程式碼中執行各種各樣的事情。您可以檢視 MDN API 索引頁面來了解。

常見瀏覽器 API

特別是,您將使用(並且我們將在本模組中更詳細介紹)最常見的瀏覽器 API 類別是:

  • 用於操作載入到瀏覽器中的文件的 API。最明顯的例子是 DOM(文件物件模型)API,它允許您操作 HTML 和 CSS——建立、刪除和更改 HTML,動態地將新樣式應用於您的頁面等。例如,每次您看到頁面上彈出視窗或顯示新內容時,那就是 DOM 在發揮作用。在 DOM 指令碼簡介中瞭解更多關於這些型別的 API 的資訊。
  • 從伺服器獲取資料以自行更新網頁小部分的 API 非常常用。這個看似微小的細節對網站的效能和行為產生了巨大影響——如果您只需要即時更新股票列表或可用新聞故事列表,而無需從伺服器重新載入整個頁面,這會讓網站或應用程式感覺更具響應性和“敏捷”。用於此的主要 API 是 Fetch API,儘管舊程式碼可能仍使用 XMLHttpRequest API。您可能還會遇到 AJAX 一詞,它描述了這種技術。在 使用 JavaScript 傳送網路請求中瞭解更多關於此類 API 的資訊。
  • 用於繪製和操作圖形的 API 在瀏覽器中得到廣泛支援——最受歡迎的是 CanvasWebGL,它們允許您以程式設計方式更新 HTML <canvas> 元素中包含的畫素資料,以建立 2D 和 3D 場景。例如,您可以使用 Canvas API 繪製矩形或圓形等形狀,將影像匯入畫布並對其應用諸如棕褐色或灰度等濾鏡,或者使用 WebGL 建立具有光照和紋理的複雜 3D 場景。此類 API 通常與用於建立動畫迴圈的 API(例如 window.requestAnimationFrame())及其他 API 結合使用,以製作像卡通和遊戲那樣不斷更新的場景。
  • 音訊和影片 API,如 HTMLMediaElementWeb Audio APIWebRTC,允許您透過多媒體做一些非常有趣的事情,例如為播放音訊和影片建立自定義 UI 控制元件,在影片中顯示字幕和副標題等文字軌道,從網路攝像頭獲取影片以透過畫布(見上文)進行操作或在網路會議中顯示給其他人的計算機,或向音軌新增效果(例如增益、失真、聲像等)。
  • 裝置 API 允許您與裝置硬體互動:例如,使用 地理定位 API 訪問裝置 GPS 以查詢使用者位置。
  • 客戶端儲存 API 使您能夠將資料儲存在客戶端,因此您可以建立一個應用程式,在頁面載入之間儲存其狀態,甚至可以在裝置離線時工作。有多種選項可用,例如使用 Web Storage API 進行簡單的名稱/值儲存,以及使用 IndexedDB API 進行更復雜的資料庫儲存。

常見第三方 API

第三方 API 種類繁多;其中一些您遲早可能會用到的更受歡迎的有:

  • 地圖 API,例如 MapquestGoogle Maps API,它們允許您在網頁上處理各種地圖相關事務。
  • Facebook API 套件,它使您能夠利用 Facebook 生態系統的各個部分來造福您的應用程式,例如透過 Facebook 登入提供應用程式登入、接受應用內支付、推出有針對性的廣告活動等。
  • Telegram API,它除了支援機器人之外,還允許您將 Telegram 頻道的內容嵌入到您的網站中。
  • YouTube API,它允許您在您的網站上嵌入 YouTube 影片、搜尋 YouTube、建立播放列表等等。
  • Pinterest API,它提供了管理 Pinterest 看板和圖釘的工具,以便將它們包含在您的網站中。
  • Twilio API,它提供了一個框架,用於在您的應用程式中構建語音和視訊通話功能,從您的應用程式傳送 SMS/MMS 等。
  • Disqus API,它提供了一個可以整合到您網站的評論平臺。
  • Mastodon API,它使您能夠以程式設計方式操縱 Mastodon 社交網路的功能。
  • IFTTT API,它能夠透過一個平臺整合多個 API。

API 如何工作?

不同的 JavaScript API 的工作方式略有不同,但通常它們具有共同的特性和相似的工作主題。

它們基於物件

您的程式碼使用一個或多個 JavaScript 物件與 API 互動,這些物件充當 API 使用的資料(包含在物件屬性中)和 API 提供的功能(包含在物件方法中)的容器。

注意:如果您還不熟悉物件的工作原理,您應該返回並完成我們的 JavaScript 物件模組,然後再繼續。

讓我們回到 Web 音訊 API 的例子——這是一個相當複雜的 API,由許多物件組成。最明顯的有:

  • AudioContext,它代表一個可以用於操縱在瀏覽器中播放的音訊的音訊圖,並擁有許多可用於操縱該音訊的方法和屬性。
  • MediaElementAudioSourceNode,它代表一個包含您希望在音訊上下文中播放和操縱的聲音的 <audio> 元素。
  • AudioDestinationNode,它代表音訊的目的地,即您的計算機上實際輸出音訊的裝置——通常是您的揚聲器或耳機。

那麼這些物件是如何互動的呢?如果您檢視我們的 簡單 Web 音訊示例也可在此處檢視即時效果),您將首先看到以下 HTML:

html
<audio src="outfoxing.mp3"></audio>

<button class="paused">Play</button>
<br />
<input type="range" min="0" max="1" step="0.01" value="1" class="volume" />

首先,我們包含一個 <audio> 元素,用於將 MP3 嵌入到頁面中。我們不包含任何預設的瀏覽器控制元件。接下來,我們包含一個 <button>,我們將用它來播放和停止音樂,以及一個型別為 range 的 <input> 元素,我們將用它來在歌曲播放時調整音軌的音量。

接下來,讓我們看看這個例子的 JavaScript。

我們首先建立一個 AudioContext 例項,在其中操作我們的音軌:

js
const audioCtx = new AudioContext();

接下來,我們建立常量來儲存對我們的 <audio><button><input> 元素的引用,並使用 AudioContext.createMediaElementSource() 方法建立一個 MediaElementAudioSourceNode,代表我們音訊的來源——將從中播放 <audio> 元素:

js
const audioElement = document.querySelector("audio");
const playBtn = document.querySelector("button");
const volumeSlider = document.querySelector(".volume");

const audioSource = audioCtx.createMediaElementSource(audioElement);

接下來,我們添加了幾個事件處理程式,用於在按鈕按下時在播放和暫停之間切換,並在歌曲播放完畢後將顯示重置到開頭:

js
// play/pause audio
playBtn.addEventListener("click", () => {
  // check if context is in suspended state (autoplay policy)
  if (audioCtx.state === "suspended") {
    audioCtx.resume();
  }

  // if track is stopped, play it
  if (playBtn.getAttribute("class") === "paused") {
    audioElement.play();
    playBtn.setAttribute("class", "playing");
    playBtn.textContent = "Pause";
    // if track is playing, stop it
  } else if (playBtn.getAttribute("class") === "playing") {
    audioElement.pause();
    playBtn.setAttribute("class", "paused");
    playBtn.textContent = "Play";
  }
});

// if track ends
audioElement.addEventListener("ended", () => {
  playBtn.setAttribute("class", "paused");
  playBtn.textContent = "Play";
});

注意:你們中的一些人可能會注意到,用於播放和暫停音軌的 play()pause() 方法不屬於 Web 音訊 API;它們是 HTMLMediaElement API 的一部分,後者不同但密切相關。

接下來,我們使用 AudioContext.createGain() 方法建立一個 GainNode 物件,該物件可用於調節透過它的音訊音量,並建立另一個事件處理程式,該處理程式在滑塊值更改時更改音訊圖的增益(音量)值:

js
// volume
const gainNode = audioCtx.createGain();

volumeSlider.addEventListener("input", () => {
  gainNode.gain.value = volumeSlider.value;
});

為了使其正常工作,最後要做的是連線音訊圖中的不同節點,這可以透過在每種節點型別上可用的 AudioNode.connect() 方法來完成:

js
audioSource.connect(gainNode).connect(audioCtx.destination);

音訊從源開始,然後連線到增益節點,以便可以調節音訊的音量。增益節點再連線到目標節點,以便聲音可以在您的計算機上播放(AudioContext.destination 屬性表示您的計算機硬體上可用的預設 AudioDestinationNode,例如您的揚聲器)。

它們有可識別的入口點

使用 API 時,您應該確保知道 API 的入口點在哪裡。在 Web 音訊 API 中,這非常簡單——它是 AudioContext 物件,需要使用它來執行任何音訊操作。

文件物件模型(DOM)API 也有一個簡單的入口點——它的功能通常出現在 Document 物件或您想以某種方式影響的 HTML 元素的例項上,例如:

js
const em = document.createElement("em"); // create a new em element
const para = document.querySelector("p"); // reference an existing p element
em.textContent = "Hello there!"; // give em some text content
para.appendChild(em); // embed em inside para

Canvas API 也依賴於獲取上下文物件來操作事物,儘管在這種情況下,它是一個圖形上下文而不是音訊上下文。它的上下文物件是透過獲取對您要繪製的 <canvas> 元素的引用,然後呼叫其 HTMLCanvasElement.getContext() 方法來建立的:

js
const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");

我們想對畫布做的任何事情都透過呼叫上下文物件(它是 CanvasRenderingContext2D 的一個例項)的屬性和方法來實現,例如:

js
Ball.prototype.draw = function () {
  ctx.beginPath();
  ctx.fillStyle = this.color;
  ctx.arc(this.x, this.y, this.size, 0, 2 * Math.PI);
  ctx.fill();
};

注意:您可以在我們的 彈跳球演示中看到此程式碼的實際執行(也可在此處檢視即時執行)。

它們通常使用事件來處理狀態變化

我們已經在課程早期的 事件簡介文章中討論過事件,該文章詳細介紹了客戶端 Web 事件是什麼以及它們如何在程式碼中使用。如果您還不熟悉客戶端 Web API 事件的工作原理,您應該先閱讀這篇文章,然後再繼續。

有些 Web API 不包含事件,但大多數至少包含幾個。允許我們在事件觸發時執行函式的處理程式屬性通常列在我們的參考資料中單獨的“事件處理程式”部分。

我們已經在上面的 Web 音訊 API 示例中看到了許多事件處理程式的用法:

js
// play/pause audio
playBtn.addEventListener("click", () => {
  // check if context is in suspended state (autoplay policy)
  if (audioCtx.state === "suspended") {
    audioCtx.resume();
  }

  // if track is stopped, play it
  if (playBtn.getAttribute("class") === "paused") {
    audioElement.play();
    playBtn.setAttribute("class", "playing");
    playBtn.textContent = "Pause";
    // if track is playing, stop it
  } else if (playBtn.getAttribute("class") === "playing") {
    audioElement.pause();
    playBtn.setAttribute("class", "paused");
    playBtn.textContent = "Play";
  }
});

// if track ends
audioElement.addEventListener("ended", () => {
  playBtn.setAttribute("class", "paused");
  playBtn.textContent = "Play";
});

它們在適當情況下具有額外的安全機制

WebAPI 功能受到與 JavaScript 和其他 Web 技術(例如同源策略)相同的安全考慮,但它們有時具有額外的安全機制。例如,一些更現代的 WebAPI 僅在透過 HTTPS 提供的頁面上有效,因為它們傳輸可能敏感的資料(示例包括 Service WorkersPush)。

此外,某些 WebAPI 在您的程式碼中呼叫它們時,會請求使用者允許啟用。例如,通知 API 使用彈出對話方塊請求許可權:

A screenshot of the notifications pop-up dialog provided by the Notifications API of the browser. 'mdn.github.io' website is asking for permissions to push notifications to the user-agent with an X to close the dialog and drop-down menu of options with 'always receive notifications' selected by default.

Web 音訊和 HTMLMediaElement API 受一項稱為自動播放策略的安全機制限制——這基本上意味著您不能在頁面載入時自動播放音訊——您必須允許使用者透過按鈕等控制元件來啟動音訊播放。這樣做是因為自動播放音訊通常非常煩人,我們真的不應該讓我們的使用者遭受這種困擾。

注意:根據瀏覽器的嚴格程度,此類安全機制甚至可能會阻止示例在本地執行,即如果您在瀏覽器中載入本地示例檔案而不是從 Web 伺服器執行它。在撰寫本文時,我們的 Web 音訊 API 示例在 Google Chrome 上無法在本地工作——我們必須將其上傳到 GitHub 才能使其工作。

總結

至此,您應該對 API 是什麼、它們如何工作以及如何在 JavaScript 程式碼中使用它們有了很好的瞭解。您可能迫不及待地想開始使用特定的 API 做一些有趣的事情,那麼讓我們開始吧!接下來,我們將介紹影片和音訊 API。