タイトル: API
SEOタイトル: HTML5 / Web API 完全ガイド
この本文には実行可能なタグ等が含まれるため、安全のためHTMLソースとして表示しています。本文データは変更していません。
<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;background:#fffbea;border:1px solid #f4c430;margin:1em 0;width:100%"><tr><td style="background:#f4c430;color:#000;font-weight:bold;padding:8px">この記事の要点</td></tr><tr><td style="padding:10px"><ul><li><strong>Web API</strong> = ブラウザが提供し、JavaScript から呼べるインターフェースの総称</li><li>分類: <strong>DOM 系</strong> (DOM, Fetch) / <strong>UI 系</strong> (Canvas, WebGL, Audio) / <strong>デバイス系</strong> (Geolocation, Bluetooth) / <strong>背景処理系</strong> (Worker, Service Worker)</li><li>標準化: <strong>W3C</strong> (主に古い API) と <strong>WHATWG</strong> (HTML Living Standard など現代の主要 API)</li><li><code>caniuse.com</code> でブラウザ対応を必ず確認。古いブラウザ向けには Polyfill / Feature Detection</li><li>Service Worker / Web Push などの<strong>強力な API は HTTPS 必須</strong> (localhost を除く)</li></ul></td></tr></table>
<h2>Web API とは</h2>
<p><strong>Web API</strong> は、ブラウザが JavaScript から呼べるように提供している組み込み機能の総称です。HTML5 と並んで現代の Web プラットフォームを構成する核となる仕様群です。</p>
<p>たとえば <code>fetch('/api/users')</code> でリクエストが飛ぶのも、<code>document.querySelector('.btn')</code> で DOM 操作できるのも、これらの Web API が JS から呼べるからです。</p>
<h2>主要な分類</h2>
<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e3f2fd"><th>カテゴリ</th><th>API 例</th><th>用途</th></tr></thead>
<tbody>
<tr><td>DOM / コア</td><td>DOM, Fetch, URL, FormData</td><td>HTML 操作、HTTP 通信</td></tr>
<tr><td>ストレージ</td><td>localStorage, sessionStorage, IndexedDB, Cache</td><td>クライアントデータ保存</td></tr>
<tr><td>グラフィック</td><td>Canvas 2D, WebGL, WebGPU, SVG</td><td>描画 / 3D</td></tr>
<tr><td>メディア</td><td>Web Audio, Media Stream, WebRTC, WebCodecs</td><td>音声 / カメラ / リアルタイム通信</td></tr>
<tr><td>背景処理</td><td>Web Workers, Service Worker, SharedWorker</td><td>並列・PWA</td></tr>
<tr><td>UI / 入力</td><td>Pointer Events, Gamepad, Web Speech</td><td>入力デバイス</td></tr>
<tr><td>デバイス</td><td>Geolocation, Bluetooth, USB, Sensor</td><td>位置・周辺機器</td></tr>
<tr><td>セキュリティ</td><td>WebAuthn, Credential Management, Web Crypto</td><td>認証 / 暗号</td></tr>
<tr><td>支払い</td><td>Payment Request, Payment Handler</td><td>決済統合</td></tr>
<tr><td>監視</td><td>IntersectionObserver, ResizeObserver, MutationObserver, PerformanceObserver</td><td>変化検知</td></tr>
</tbody>
</table>
<h2>DOM API</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// 要素取得 / 操作
const btn = document.querySelector('#submit');
btn.addEventListener('click', () => alert('clicked'));
// 動的生成
const li = document.createElement('li');
li.textContent = 'item';
li.classList.add('item');
document.querySelector('ul').appendChild(li);
// 属性 / データ
btn.setAttribute('disabled', '');
btn.dataset.userId = '123'; // <button data-user-id="123"></code></pre>
<h2>Fetch / XHR / WebSocket</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// Fetch (XHR の現代版)
const res = await fetch('/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'taro' }),
});
const json = await res.json();
// AbortController でキャンセル可能
const ctrl = new AbortController();
fetch('/slow', { signal: ctrl.signal });
setTimeout(() => ctrl.abort(), 3000);
// WebSocket (双方向通信)
const ws = new WebSocket('wss://example.com/ws');
ws.onmessage = (e) => console.log(e.data);
ws.send('hello');
// Server-Sent Events (片方向)
const sse = new EventSource('/events');
sse.onmessage = (e) => console.log(e.data);</code></pre>
<h2>Storage 系</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// localStorage: 永続化 (5-10 MB)
localStorage.setItem('theme', 'dark');
const theme = localStorage.getItem('theme');
// sessionStorage: タブ閉じたら消える
sessionStorage.setItem('csrf', 'xyz');
// IndexedDB: 大容量 (数百 MB) NoSQL
const req = indexedDB.open('myDb', 1);
req.onupgradeneeded = (e) => {
const db = e.target.result;
db.createObjectStore('users', { keyPath: 'id' });
};
// Cache API (Service Worker と相性◎)
const cache = await caches.open('v1');
await cache.put('/index.html', new Response('...'));
const cached = await cache.match('/index.html');</code></pre>
<h2>Canvas / WebGL</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// Canvas 2D
const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#3498db';
ctx.fillRect(10, 10, 100, 50);
ctx.beginPath();
ctx.arc(200, 50, 40, 0, Math.PI * 2);
ctx.fill();
// WebGL (低レベル 3D)
const gl = canvas.getContext('webgl2');
// WebGPU (次世代、Chrome 113+)
const adapter = await navigator.gpu.requestAdapter();
const device = await adapter.requestDevice();</code></pre>
<h2>メディア系 (Audio, WebRTC)</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// Web Audio (合成、エフェクト)
const audioCtx = new AudioContext();
const osc = audioCtx.createOscillator();
osc.frequency.value = 440; // 440Hz (ラ)
osc.connect(audioCtx.destination);
osc.start();
setTimeout(() => osc.stop(), 1000);
// マイク / カメラ
const stream = await navigator.mediaDevices.getUserMedia({
audio: true, video: true,
});
document.querySelector('video').srcObject = stream;
// WebRTC (P2P 通信)
const pc = new RTCPeerConnection();
pc.addTrack(stream.getVideoTracks()[0], stream);
// Web Speech (音声認識・合成)
const rec = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
rec.onresult = (e) => console.log(e.results[0][0].transcript);
rec.start();
speechSynthesis.speak(new SpeechSynthesisUtterance('こんにちは'));</code></pre>
<h2>Background API</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// Web Worker (CPU 重い処理を別スレッド)
const worker = new Worker('/heavy.js');
worker.postMessage({ data: largeArray });
worker.onmessage = (e) => console.log(e.data);
// Service Worker (PWA, オフライン, プッシュ通知)
navigator.serviceWorker.register('/sw.js');
// sw.js 側
self.addEventListener('fetch', (e) => {
e.respondWith(
caches.match(e.request).then(r => r || fetch(e.request))
);
});
// Notifications
await Notification.requestPermission();
new Notification('完了', { body: 'アップロードが完了' });</code></pre>
<h2>Observer 系</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// IntersectionObserver: 要素が画面に入った検知 (遅延読み込み)
const io = new IntersectionObserver(entries => {
for (const e of entries) {
if (e.isIntersecting) {
e.target.src = e.target.dataset.src;
io.unobserve(e.target);
}
}
});
document.querySelectorAll('img[data-src]').forEach(img => io.observe(img));
// ResizeObserver: 要素サイズ変化検知
new ResizeObserver(entries => {
console.log(entries[0].contentRect.width);
}).observe(document.body);
// MutationObserver: DOM 変化検知
new MutationObserver(muts => console.log(muts))
.observe(document.body, { childList: true, subtree: true });
// PerformanceObserver: パフォーマンスメトリクス
new PerformanceObserver(list => {
for (const e of list.getEntries()) console.log(e);
}).observe({ entryTypes: ['largest-contentful-paint'] });</code></pre>
<h2>デバイス系</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// Geolocation
navigator.geolocation.getCurrentPosition(pos => {
console.log(pos.coords.latitude, pos.coords.longitude);
});
// Web Bluetooth (Chrome 系)
const device = await navigator.bluetooth.requestDevice({
filters: [{ services: ['battery_service'] }],
});
// Web USB
const usb = await navigator.usb.requestDevice({ filters: [] });
// Gamepad
window.addEventListener('gamepadconnected', e => {
console.log(e.gamepad.id);
});
// DeviceOrientation (スマホ傾き)
window.addEventListener('deviceorientation', e => {
console.log(e.alpha, e.beta, e.gamma);
});</code></pre>
<h2>セキュリティ系</h2>
<pre style="background:#1e293b;color:#e2e8f0;padding:1em;border-radius:6px;overflow-x:auto;line-height:1.5"><code class="language-javascript">// WebAuthn (パスキー、生体認証)
const cred = await navigator.credentials.create({
publicKey: { challenge: new Uint8Array(32), rp: { name: 'My App' }, ... },
});
// Web Crypto API
const data = new TextEncoder().encode('hello');
const hash = await crypto.subtle.digest('SHA-256', data);
const hex = Array.from(new Uint8Array(hash))
.map(b => b.toString(16).padStart(2, '0')).join('');
// 安全な乱数
const buf = new Uint8Array(16);
crypto.getRandomValues(buf);</code></pre>
<h2>標準化団体</h2>
<table border="1" cellpadding="6" cellspacing="0" style="border-collapse:collapse;width:100%">
<thead><tr style="background:#e8f5e9"><th>団体</th><th>主な仕様</th></tr></thead>
<tbody>
<tr><td><a href="https://www.w3.org/" target="_blank">W3C</a></td><td>CSS, ARIA, Web Crypto, WebRTC, WebAuthn (Editor 機関)</td></tr>
<tr><td><a href="https://whatwg.org/" target="_blank">WHATWG</a></td><td>HTML Living Standard, DOM, Fetch, URL, Streams</td></tr>
<tr><td><a href="https://tc39.es/" target="_blank">TC39</a></td><td>ECMAScript (JavaScript 言語本体)</td></tr>
<tr><td><a href="https://www.khronos.org/" target="_blank">Khronos</a></td><td>WebGL, WebGPU (3D グラフィック)</td></tr>
</tbody>
</table>
<h2>HTTPS 必須の API</h2>
<p>セキュリティクリティカルな API は <strong>Secure Context</strong> (HTTPS or localhost) 必須:</p>
<ul>
<li>Service Worker / PWA</li>
<li>Web Push / Notifications</li>
<li>Geolocation</li>
<li>Web Bluetooth / USB</li>
<li>Web Crypto (一部)</li>
<li>Clipboard API (書込)</li>
</ul>
<h2>FAQ</h2>
<p><strong>Q: ブラウザ対応を確認したい</strong><br />
A: <a href="https://caniuse.com/" target="_blank">caniuse.com</a> が定番。MDN ドキュメントの各 API ページにも対応表があります。</p>
<p><strong>Q: 古いブラウザで動かない</strong><br />
A: Polyfill (core-js, whatwg-fetch) で機能補完するか、Feature Detection で代替動作にフォールバック。</p>
<p><strong>Q: REST API と Web API の違いは?</strong><br />
A: 別物。REST API はサーバ側 HTTP エンドポイント (例: <code>GET /api/users</code>)。本記事の Web API はブラウザ提供の JS インターフェースです。</p>