Web API 簡介

首先,我們將從高層次的角度來了解 API——它們是什麼,它們是如何工作的,如何在程式碼中使用它們,以及它們的結構?我們還將看一下 API 的不同主要類別,以及它們都有哪些用途。

先決條件 HTMLCSS 和 JavaScript 基礎知識的瞭解(參見 入門構建塊JavaScript 物件)。
目標 熟悉 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.

圖片來源:超載插座 by The Clear Communication People, on Flickr.

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

注意:另請參見 API 詞彙表條目 以獲取更多描述。

客戶端 JavaScript 中的 API

尤其是客戶端 JavaScript,它可以使用許多可用的 API——這些 API 不是 JavaScript 語言本身的一部分,而是構建在核心 JavaScript 語言之上,為你在 JavaScript 程式碼中使用提供了額外的超能力。它們通常分為兩類

  • 瀏覽器 API 構建在你的 Web 瀏覽器中,並且能夠公開來自瀏覽器和周圍計算機環境的資料,並使用它做一些有用的複雜的事情。例如,Web 音訊 API 為 JavaScript 提供了用於在瀏覽器中操作音訊的結構——獲取音訊軌道,更改其音量,對其應用效果等。在後臺,瀏覽器實際上正在使用一些複雜的低階程式碼(例如 C++ 或 Rust)來執行實際的音訊處理。但是,API 又將這種複雜性從你身邊抽象出來。
  • 第三方 API 預設情況下不會內建在瀏覽器中,通常你必須從 Web 上的某個地方檢索它們的程式碼和資訊。例如,Google 地圖 API 允許你執行諸如在你的網站上顯示到辦公室的互動式地圖之類的事情。它提供了一組特殊的結構,你可以使用它們來查詢 Google 地圖服務並返回特定資訊。

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 在起作用。在 操作文件 中瞭解更多關於這些型別的 API 的資訊。
  • 從伺服器獲取資料以自行更新網頁的小部分的 API 被廣泛使用。這個看似很小的細節對網站的效能和行為產生了巨大的影響——如果你只需要更新股票清單或可用新故事列表,那麼無需重新載入整個頁面就可以立即執行此操作,這可以使網站或應用程式感覺更具響應性和“快速”。用於此的主要 API 是 Fetch API,雖然較舊的程式碼可能仍在使用 XMLHttpRequest API。你可能還會遇到術語 Ajax,它描述了這種技術。在 從伺服器獲取資料 中瞭解更多關於此類 API 的資訊。
  • 用於繪製和操作圖形的 API 在瀏覽器中得到廣泛支援——最流行的是 CanvasWebGL,它們允許你以程式設計方式更新包含在 HTML <canvas> 元素中的畫素資料以建立 2D 和 3D 場景。例如,你可以使用 Canvas API 繪製矩形或圓圈之類的形狀,將影像匯入畫布,並對其應用諸如棕褐色或灰度之類的濾鏡,或者使用 WebGL 建立具有照明和紋理的複雜 3D 場景。此類 API 通常與用於建立動畫迴圈(例如 window.requestAnimationFrame())和其他 API 結合使用,以製作不斷更新的場景,如卡通和遊戲。
  • 音訊和影片 APIHTMLMediaElementWeb 音訊 APIWebRTC 允許你使用多媒體做一些非常有趣的事情,例如為播放音訊和影片建立自定義 UI 控制元件,與你的影片一起顯示字幕和字幕之類的文字軌道,從你的網路攝像頭獲取影片以透過畫布(見上文)進行操作或顯示在網路會議中其他人的計算機上,或者向音訊軌道新增效果(例如增益、失真、平移等)。
  • 裝置 API 使你能夠與裝置硬體互動:例如,使用 地理位置 API 訪問裝置 GPS 以查詢使用者的位置。
  • 客戶端儲存 API 使你能夠在客戶端儲存資料,這樣你就可以建立一個應用程式,該應用程式將在頁面載入之間儲存其狀態,甚至在裝置離線時也能工作。有幾種可用的選項,例如使用 Web 儲存 API 進行簡單的名稱/值儲存,以及使用 IndexedDB API 進行更復雜的資料庫儲存。

常見的第三方 API

第三方 API 種類繁多;你遲早可能會使用的一些更流行的 API 是

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

API 是如何工作的?

不同的 JavaScript API 以略微不同的方式工作,但通常,它們具有共同的功能和類似的工作主題。

它們基於物件

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

注意:如果你還不熟悉物件的運作方式,你應該在繼續之前回顧並完成我們的 JavaScript 物件 模組。

讓我們回到 Web Audio 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>,我們將使用它來播放和停止音樂,以及一個型別為範圍的 <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 Audio 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 Audio 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 Audio 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 在您程式碼中對它們進行呼叫後,會請求使用者允許啟用它們。例如,Notifications 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 Audio 和 HTMLMediaElement API 受稱為 自動播放策略 的安全機制的約束——這基本上意味著您無法在頁面載入時自動播放音訊——您必須允許您的使用者透過按鈕之類的控制元件來啟動音訊播放。這樣做是為了防止自動播放音訊,因為自動播放音訊通常非常令人討厭,我們不應該強迫使用者忍受它。

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

總結

此時,您應該對什麼是 API、它們如何工作以及您可以在 JavaScript 程式碼中使用它們做什麼有一個很好的瞭解。您可能很興奮想要開始實際使用特定的 API 來做一些有趣的事情,所以讓我們開始吧!接下來,我們將看看如何使用文件物件模型 (DOM) 來操作文件。