JavaScript APIは、JavaScriptから呼び出せる機能の窓口です。言語の組み込み機能、ブラウザ標準のWeb API、外部サービスのAPIの3種類があり、多くの場合はブラウザが標準で備えるWeb APIを指します。ページを書き換えるDOM、サーバーと通信するFetchやWebSocket、データを保存するWeb Storageなどがあり、ライブラリを入れなくてもそのまま使えます。この記事では主要なAPIを用途別の一覧で整理し、外部のAPIをfetchで呼び出す手順と失敗したときの挙動、XMLHttpRequest(Ajax)との違い、HTTPSでないと動かないAPI、Node.jsでも使えるAPIまでをコード付きで解説します。なお、Javaの標準ライブラリ(Java API)はJavaScriptとは別の言語の話なので、この記事では扱いません。
まとめ:JavaScript APIの一覧と使い分けの要点
よく使うAPIと入口、Node.jsでそのまま使えるかを1つの表にしました(Node.jsの列はNode.js 26.5.0でグローバルに存在するかを確認した結果です)。
| API | 入口 | 用途 | Node.js |
|---|---|---|---|
| DOM | document.querySelector() |
要素の取得・変更 | なし |
| Fetch | fetch() |
HTTP通信 | あり |
| XMLHttpRequest | new XMLHttpRequest() |
旧来のHTTP通信 | なし |
| WebSocket | new WebSocket() |
双方向通信 | あり |
| Web Storage | localStorage |
文字列の保存 | 要フラグ |
| IndexedDB | indexedDB.open() |
構造化データの保存 | なし |
| History | history.pushState() |
URLの書き換え | なし |
| Geolocation | navigator.geolocation |
位置情報 | なし |
| Clipboard | navigator.clipboard |
コピー・貼り付け | なし |
- サーバーからデータを取るなら、新しく書くコードは
fetch()で書きます。XMLHttpRequestを選ぶのは、アップロードの進捗バーが必要なときと既存コードの保守くらいです。 fetch()は404や500が返ってきてもエラーになりません。response.okを確認しないと、エラー画面のHTMLを正常なデータとして扱ってしまいます。- Geolocation・Clipboard・Service Workerなどは、HTTPSか
localhostで開いたページでしか動きません。スマホ実機からhttp://192.168.x.xで開くと動かないのはこのためです。 - Google Maps JavaScript APIのような外部サービスのAPIは、ブラウザ標準のWeb APIとは別物です。APIキーの発行や課金の設定が要ります。
JavaScript APIの3つの層:言語の機能・ブラウザのWeb API・外部サービスのAPI
「JavaScript API」という言葉は、次の3つのどれかを指して使われます。どれの話かを先に決めておくと、調べる場所と動く環境を間違えずに済みます。
| 層 | 例 | 仕様を決める団体 | 動く場所 |
|---|---|---|---|
| 言語の組み込み機能 | Array・Promise・JSON・Map |
Ecma International TC39 | ブラウザ・Node.jsの両方 |
| ブラウザのWeb API | DOM・fetch()・localStorage |
WHATWG・W3C | ブラウザ(一部はNode.jsにも) |
| 外部サービスのAPI | Google Maps JavaScript API | 提供する各社 | 読み込んだページ |
MDNのWeb API の紹介も、ブラウザーAPIは「JavaScript 言語本体の一部ではなく」その上に築かれたもので、サードパーティAPIは既定ではブラウザーに組み込まれていない、と分けて説明しています。JSON.parse()はNode.jsでも動くのにdocumentは動かない、という違いは、言語の機能とブラウザのAPIの差から来ています。
用途別の主要なWeb API一覧
ブラウザのWeb APIは数百あり、全体はMDNのWeb API 索引で引けます。業務のWebアプリでまず触るのは、次の用途別の顔ぶれです。
| 用途 | 主なAPI |
|---|---|
| ページの操作 | DOM・Intersection Observer・Resize Observer |
| 通信 | Fetch・WebSocket・Server-Sent Events |
| 保存 | Web Storage・IndexedDB・Cache |
| 画面遷移・ウィンドウ | History・Window(open・scrollTo) |
| 端末・権限 | Geolocation・Clipboard・Notifications |
| 描画・メディア | Canvas・WebGL・Web Audio・WebRTC |
| 並行処理 | Web Workers・BroadcastChannel・Web Locks |
以下では、検索で特に調べられているDOM・Fetch・WebSocketと、ウィンドウ・履歴・保存の扱い方を順に説明します。
DOM APIによる要素の取得・変更
DOMはHTMLをツリー構造のオブジェクトとして扱うAPIです。要素の取得はquerySelector()(最初の1件)とquerySelectorAll()(全件)で足ります。
<button id="add">追加</button>
<ul id="list"></ul>
<script>
const button = document.querySelector('#add');
const list = document.querySelector('#list');
button.addEventListener('click', () => {
const li = document.createElement('li');
li.textContent = `項目 ${list.children.length + 1}`;
list.append(li);
});
</script>
文字を入れるときはinnerHTMLではなくtextContentを使います。innerHTMLにユーザー入力を入れると、文字列中のHTMLがそのまま解釈され、クロスサイトスクリプティング(XSS)の入口になります。HTMLを組み立てたい場合も、createElement()で要素を作ってtextContentで中身を入れる書き方にすると安全です。
上の例はスクリプトを要素より後ろに置いているので動きます。同じコードを<head>のインラインスクリプトに移すと、実行時点ではまだ#addが存在せず、querySelector()がnullを返してaddEventListenerの呼び出しで止まります。<head>に置く場合は、コードを外部ファイルに移してsrc属性とdefer属性を指定します。インラインスクリプトにはdeferは効きません。
Fetch APIで外部のAPIを呼び出す手順
サーバーや外部サービスのAPIからデータを取る処理は、fetch()とasync/awaitで書くのが現在の標準です。非同期処理そのものの考え方は非同期処理とは?同期処理との違いから実装方式まで実装者目線で解説で扱っています。以下の例のapi.example.comは実際の接続先に置き換えてください。関数の外でawaitを書いている例は、type="module"のスクリプトかasync関数の中で動かします。
GETによるJSON取得とresponse.okによる成功判定
async function getUser(id) {
const res = await fetch(`https://api.example.com/users/${id}`);
if (!res.ok) {
throw new Error(`HTTP ${res.status}`);
}
return res.json();
}
if (!res.ok)の3行が要です。MDNのfetch()の解説は、fetch()のPromiseは不正なURLやネットワークエラー、中断などでrejectしますが、404や504のようなエラーのステータスではrejectしない、と明記しています。okはステータスが200〜299のときだけtrueになります。
POSTによるJSON送信とContent-Typeの指定
const res = await fetch('https://api.example.com/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'issoh' }),
});
if (!res.ok) {
throw new Error(`HTTP ${res.status}`);
}
bodyに通常のオブジェクトをそのまま渡すと、JSONではなく[object Object]という文字列が送られます。JSON.stringify()で文字列にし、Content-Typeヘッダーで形式を伝えます。
AbortSignal.timeout()による待ち時間の制限
fetch()には時間切れの設定項目がありません。実行環境側のタイムアウトだけではアプリが求める待ち時間を保証できないため、外部APIを呼ぶときはsignalにAbortSignal.timeout()を渡します。MDNのAbortSignal.timeout()によると、時間切れの例外名はTimeoutErrorで、ユーザー操作などで中断したときのAbortErrorと区別できます。ただしMDNの互換性データでは、ChromeとEdgeが時間切れをTimeoutErrorで返すのは124からで、103〜123ではAbortErrorになります。古いブラウザも対象なら、両方の名前を時間切れとして扱います。
const url = 'https://api.example.com/users/1';
try {
const res = await fetch(url, { signal: AbortSignal.timeout(5000) });
} catch (err) {
if (err.name === 'TimeoutError') {
// 5秒以内に応答が無かった
} else if (err.name === 'AbortError') {
// AbortControllerで中断した
} else {
throw err; // TypeError(ネットワークエラーやCORSの拒否)などは呼び出し元へ
}
}
失敗パターン別の挙動:rejectするもの・しないもの
どの失敗がcatchに来て、どの失敗が来ないのかを整理しました。Node.js 26.5.0のfetch()(ブラウザと同じFetch仕様の実装)で、node:httpで立てたローカルサーバーへ各状況を発生させたときの結果で、ブラウザでもFetch仕様どおり同じ分かれ方になります。
| 状況 | 結果 | 例外名 |
|---|---|---|
| 404が返る | resolve(okはfalse) |
なし |
HTMLにres.json() |
reject | SyntaxError |
AbortSignal.timeout()切れ |
reject | TimeoutError |
AbortControllerで中断 |
reject | AbortError |
| 存在しないホスト | reject | TypeError |
| 本文を2回読む | reject | TypeError |
2行目は、404や500のときにサーバーがHTMLのエラーページを返し、それをres.json()で読もうとしてUnexpected token '<'で落ちるパターンです。HTTPエラーのときは先にres.okで分岐すればJSONの解析を避けられます。ただし、ステータスが200でも本文がHTMLや空文字列ならres.json()は失敗するので、解析の失敗は別にcatchで受けます。6行目は、ログ用にawait res.text()で読んだあとres.json()を呼んだ場合に起きます。2回使いたいときはres.clone()で複製してから読みます。複数のAPIを並列で呼ぶときの例外処理はJavaScriptの非同期エラーハンドリングと並列実行|try/catch・Promise.all・allSettledの使い分けにまとめています。
ブラウザでだけ起きるCORSエラー
ブラウザから別オリジンのAPIを呼ぶと、相手のサーバーがAccess-Control-Allow-Originヘッダーを返さない限り、レスポンスはJavaScriptに渡されずTypeErrorになります。同じURLでもcurlやNode.jsからは取れるので、「APIは正常なのにブラウザだけ失敗する」ときはまずCORSを疑います。直し方はフロント側ではなくAPIサーバー側の設定で、詳しくはCORSとは?仕組み・プリフライト・サーバー設定例・エラー解決を実装目線で解説を参照してください。
Cookieの扱いにも既定値があります。RequestInitのcredentialsは既定がsame-originで、別オリジンのAPIにログインCookieを送るにはcredentials: 'include'に加えて、サーバー側がAccess-Control-Allow-Credentialsを返し、Access-Control-Allow-Originに*ではなく具体的なオリジンを書く必要があります。社内システムと外部サービスをAPIでつなぐ設計や認証方式の選定から相談したい場合は、一創のAPI開発・システム連携でも支援しています。
Fetch APIとXMLHttpRequest(Ajax)の違い
Ajaxは「ページを再読み込みせずに通信して一部を書き換える」手法の呼び名で、APIの名前ではありません。その中身として長く使われてきたのがXMLHttpRequest(XHR)で、いまはFetchが後継です。違いは書き方の好みではなく、次の仕様の差にあります。
| 観点 | Fetch | XMLHttpRequest |
|---|---|---|
| 結果の受け取り | Promise | イベント(onload) |
| 404・500 | resolve(okで判定) |
onload(statusで判定) |
| タイムアウト | AbortSignal.timeout() |
xhr.timeout |
| アップロード進捗 | イベント無し | xhr.upload.onprogress |
| 同期通信 | 不可 | 可能だが非推奨 |
| Service Worker内 | 使える | 使えない |
| Node.js | 標準で使える | 無い |
新しく書くコードはFetchで統一します。新規実装でXHRを選ぶ理由になるのは、ファイルアップロードで進捗バーを出したい場合です。保守中のコードは、ライブラリとの互換性や移行の手間からXHRのまま残す判断もあります。Fetchには送信側の進捗イベントが無く、xhr.uploadのprogressイベントで送信済みバイト数を受け取るXHRの代わりになりません。同期XHR(open()の第3引数にfalse)は、MDNの同期・非同期リクエストの解説が「deprecated」と明記しているので、古いコードに見つけたら非同期に書き換えます。
jQueryの$.ajax()は通常XHRを使うラッパーです(JSONPの指定では<script>要素を使う別の方式になり、fetch()では置き換えられません)。jQueryを外す移行では$.ajax()をfetch()に置き換えることになりますが、jQueryは404でエラー側のコールバックを呼ぶのに対し、fetch()は呼ばないので、res.okの判定を足し忘れると移行後にエラー処理が素通りします。
WebSocket APIによる双方向通信と運用上の制約
チャットや共同編集、相場表示のように、サーバーからも任意のタイミングで送りたい場合はWebSocketを使います。本番では暗号化されたwss://を使います。
const ws = new WebSocket('wss://example.com/chat');
ws.addEventListener('open', () => ws.send(JSON.stringify({ type: 'join' })));
ws.addEventListener('message', (e) => console.log(JSON.parse(e.data)));
ws.addEventListener('close', (e) => console.log('closed', e.code));
ws.addEventListener('error', () => console.log('error'));
ws.readyStateはCONNECTING=0・OPEN=1・CLOSING=2・CLOSED=3の4状態で、OPENになる前にsend()すると例外になります。運用で効いてくる制約は2つです。
- 切れても自動で再接続しない:
closeイベントを受けたら、自分で待ち時間を伸ばしながらnew WebSocket()し直す処理が要ります。Socket.IOなどのライブラリを使う理由の多くはここです。 - 受信を抑える仕組み(バックプレッシャー)が無い:MDNのWebSocketのページは、処理より速くメッセージが届くとメモリを使い切るかCPU100%で応答しなくなると注意しています。代替として紹介されている
WebSocketStreamは、MDN上で実験的かつ非標準の扱いで、互換性データでもChromeとEdgeの124以降だけが対応し、FirefoxとSafariは未対応です。
サーバーからの一方向の配信で足りるなら、HTTPのまま自動再接続も備えるServer-Sent Eventsの方が単純です。選び方はSSEとWebSocketの違いと使い分け|WebRTC・WebTransportまで性能比較【2026年10月】、ハンドシェイクやサーバー側の実装はWebSocketとは?仕組み・ハンドシェイクからNode.js実装・運用の判断まで実装者向けに解説で解説しています。
Window・History・Web Storageによる画面操作・履歴管理・保存
windowはページの実行環境を表すオブジェクトで(iframeにもそれぞれのwindowがあります)、setTimeout()やalert()もここに属します。ウィンドウ操作には、昔の解説どおりには動かないものがあります。window.resizeTo()は、window.open()で開いたウィンドウ以外ではサイズを変えられず、タブが複数あるウィンドウでも効きません。普通のタブでresizeTo()を呼んでも何も起きないのは仕様どおりです。
// SPAでURLだけ変える(ページは再読み込みしない)
history.pushState({ page: 2 }, '', '?page=2');
// 戻る・進むボタンで呼ばれる
window.addEventListener('popstate', (e) => render(e.state));
// localStorageは文字列しか入らないのでJSONにする
try {
localStorage.setItem('settings', JSON.stringify({ theme: 'dark' }));
} catch (e) {
// 容量超過はQuotaExceededError
}
let settings = {};
try {
settings = JSON.parse(localStorage.getItem('settings') ?? '{}');
} catch (e) {
// 保存値が壊れている・ストレージが禁止されているときは既定値のまま
}
localStorageは、MDNの容量と削除基準によるとオリジンごとに5MiBまでで、超えるとQuotaExceededErrorが投げられます。同期APIなので大きなデータの読み書きはメインスレッドを止めます。数MB単位のデータや検索が必要なデータはIndexedDBに置きます。使い分けはIndexedDBのデメリットと容量上限|localStorage・Cookieとの違いと使い分けで比べています。
そのAPIが使えるかを確かめる方法
「サンプルどおりに書いたのにundefinedになる」原因は、ブラウザの対応、HTTPSの有無、実行環境の3つでほぼ説明できます。
Clipboard APIの機能検出と利用可否の判定
if ('clipboard' in navigator) {
try {
await navigator.clipboard.writeText('コピーする文字列');
} catch (err) {
// 権限が無い・ユーザー操作の外から呼んだときは拒否される
}
} else {
// 非対応・非HTTPSのときの代替処理
}
ブラウザ名やUser-Agentで分岐するより、使いたい機能があるかを直接確かめる方が確実です。ただし機能があっても、権限やユーザー操作の条件を満たさなければ呼び出しは拒否されるので、writeText()はクリックなどの操作から呼び、失敗をcatchで受けます。対応ブラウザの全体像は、MDN各ページ末尾の互換性表かCan I useで確認します。主要ブラウザすべてが対応した時期の目安として、Web Platformの「Baseline」表示も使えます。
HTTPSでしか動かないAPI:セキュアコンテキスト
MDNのセキュアコンテキスト限定の機能一覧には、Async Clipboard API・Geolocation API・Notifications API・Service Workers・Web Crypto APIのcrypto.subtle・getUserMedia()などが並んでいます(Web Crypto APIでもcrypto.getRandomValues()はHTTPのページで使えます)。安全とみなされるオリジンの代表はhttpsで、ローカル開発ではlocalhost・127.0.0.1・file:のURLも含まれます。ただし非セキュアな親ページに埋め込まれたiframeは、HTTPSでもセキュアコンテキストになりません。最終的な判定はwindow.isSecureContextで確かめます。
ここで詰まりやすいのが、PCの開発サーバーをスマホ実機からhttp://192.168.1.10:3000のようなLAN内IPで開くケースです。PC上のhttp://localhost:3000では動いたコピー機能や位置情報が、スマホでは動きません。LAN内IPは安全なオリジンに含まれないためです。window.isSecureContextがfalseならこの問題なので、開発サーバーをHTTPSで立てるか、トンネルサービスでHTTPSのURLを発行して確認します。
Node.jsで使えるWeb APIと使えないAPI
Node.jsはブラウザではありませんが、Web APIの一部を同じ名前で実装しています。Node.js 26.5.0でtypeof globalThis.<名前>を調べると、次のように分かれました。
| 区分 | API |
|---|---|
| 使える(通信) | fetch・WebSocket・AbortController・FormData |
| 使える(その他) | URL・Blob・BroadcastChannel・crypto.subtle |
| 条件付き | localStorage(--localstorage-fileの指定が必要) |
| 条件付き(実験的) | EventSource(--experimental-eventsourceが必要) |
| 無い | document・window・XMLHttpRequest・indexedDB |
Node.jsのグローバルオブジェクトの公式ドキュメントの変更履歴では、fetchは18.0.0でフラグ無しで使えるようになり21.0.0で実験的機能の扱いが外れ、WebSocketは22.0.0でフラグ無しになり22.4.0で実験的機能の扱いが外れています。現行のLTSであれば、サーバー側の処理やCLIツールでも、ブラウザと同じfetch()のコードとres.okの判定がそのまま使えます。localStorageは注意が要ります。v26.5.0のドキュメントの変更履歴には「v26.0.0から--localstorage-file無しのアクセスはDOMExceptionを投げる」とありますが、26.5.0で実行すると例外は出ずundefinedが返り、「localStorage is not available because –localstorage-file was not provided」という警告が出るだけでした。版によって例外かundefinedかが変わりうるので、Node.jsで使うときは必ず--localstorage-fileでファイルを指定します。DOMを使うコードをNode.jsでテストするときは、jsdomなどでDOMを用意する必要があります。Node.js自体の位置づけはNode.jsとは?仕組み・版の選び方・標準機能で動かす手順を実装目線で解説を参照してください。
よくある質問
JavaScript APIとは何ですか?
JavaScriptから呼び出せる機能の窓口の総称です。多くの場合は、DOM・Fetch・WebSocketなどブラウザが標準で備えるWeb APIを指します。言語に組み込まれたArrayやPromise、Google Mapsのような外部サービスが提供するAPIまで含めて呼ぶこともあります。
JavaScriptでAPIを呼び出すにはどうすればよいですか?
fetch()にURLを渡し、await res.json()で結果を受け取ります。そのときres.okで成功を確かめ、AbortSignal.timeout()で待ち時間に上限を付けます。ブラウザから別ドメインのAPIを呼ぶ場合は、API側がCORSを許可している必要があります。
FetchとAjaxは何が違いますか?
Ajaxは非同期通信でページの一部を書き換える手法の名前で、FetchはそのためのAPIの1つです。従来のXMLHttpRequestと比べると、FetchはPromiseで結果を返し、Service WorkerやNode.jsでも使えます。一方、アップロード進捗のイベントはXMLHttpRequestにしかありません。
Google Maps JavaScript APIは無料で使えますか?
Google Maps JavaScript APIはブラウザ標準のAPIではなく、Googleが提供する外部サービスのAPIです。APIキーと請求先アカウントの設定が必要な従量課金です。Google Maps Platformの料金概要によると、2025年3月1日に毎月200ドルのクレジットが廃止され、SKUごとの無料使用枠に切り替わりました。枠の数量と単価はSKUと区分(Essentials・Pro・Enterprise)で異なるので、公式の料金表で確認してください。
Web APIの一覧はどこで確認できますか?
APIを探す入口にはMDNのWeb API索引が便利です。各APIのページにブラウザ互換性表と仕様へのリンクがあり、規範となる仕様の原文はWHATWG(DOM・Fetch・HTMLなど)とW3C(Geolocationなど)が公開しています。