完成イメージ
APIを使って、ボタンをクリックするたびに異なる画像をランダムに表示してみましょう。


今回のテーマ
JavaScript の fetch() を使って、外部からデータを読み込み、
そのデータを画面に表示する方法
目的
fetch()で外部APIにアクセスしてデータを取得する.then()を使った非同期処理の流れを知る- APIから取得したJSONデータを
.innerHTMLなどで表示する
作成ファイル・保存場所
js-domフォルダに以下のファイルを作成してください。
| ファイル名 | 内容 |
|---|---|
| js-dom07.html | ボタンクリックの動作練習用HTML/js |
| js-dom__07.html | ステップアップ練習用HTML/js |
JavaScriptは <script> タグ内に直接記述してください(内部JS)
チェックポイント
- APIからJSON形式でデータを取得できているか?
- 取得したデータをHTMLとして表示できているか?
- ネットワークが失敗したときのエラー処理ができているか?
JavaScript基礎トレーニング1
猫画像を取得して表示する
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>APIで猫画像を表示しよう</title>
</head>
<body>
<h1>ランダムな猫の画像を表示</h1>
<p><button id="cat-btn">猫画像を取得する</button></p>
<div id="cat-area">
<!-- 猫の画像がここに表示されます -->
</div>
<script>
const btn = document.getElementById('cat-btn');
const catArea = document.getElementById('cat-area');
btn.addEventListener('click', () => {
fetch('https://api.thecatapi.com/v1/images/search')
.then(response => response.json())
.then(data => {
console.log(JSON.stringify(data, null, 2));
const imgUrl = data[0].url;
catArea.innerHTML = `<img src="${imgUrl}" alt="猫の画像" width="300">`;
})
.catch(error => {
catArea.textContent = '猫画像の取得に失敗しました。';
console.error('エラー:', error);
});
});
</script>
</body>
</html>
fetch のコードを分解して解説!
fetch('https://api.thecatapi.com/v1/images/search')
外部サービス(The Cat API)にアクセスして、猫の画像情報をください!とリクエストします。fetch() は「データを取りに行く命令」です。下記のようにJavaScript のアロー関数の省略構文を使って書けます。
.then(response => response.json())
取得したデータ(response)を JSON形式(データのかたまり)に変換しています。.json() は「データを読みやすい形に直すよ」という意味です。
.then(data => {
const imgUrl = data[0].url;
catArea.innerHTML = `<img src="${imgUrl}" alt="猫の画像" width="300">`;
})
.then() とは?
JavaScriptの fetch() や他の非同期処理では、「データが返ってくるまで少し時間がかかる」ことがあります。そのため、「終わったあとに〇〇をやってね!」という命令を .then() を使ってつなげて書きます。
fetch('URL')
.then(response => response.json()) // ① JSONに変換
const imgUrl = data[0].url;
catArea.innerHTML = `<img src="${imgUrl}" alt="猫の画像" width="300">`;
});
.then() を使うと「順番に処理していく」ことができます(これを「Promiseチェーン」といいます)。
このあとは、読み込んだデータ(data)から、猫画像のURLを取り出して画面に表示します。
data[0].urlは、返ってきたデータの中の「1番目の画像のURL」catArea.innerHTML = ...で、HTMLに<img>タグを入れて画像を表示します。
.catch(error => {
catArea.textContent = '猫画像の取得に失敗しました。';
console.error('エラー:', error);
});
最後は、もし画像の取得に失敗したら(ネットに繋がらないとか)、エラーメッセージを表示します。
.catch()は「失敗したときの処理」console.error()は エラーメッセージを赤文字でコンソールに出力するメソッドですconsole.error()で出力すると、デベロッパーツールのコンソールで赤字表示され、デバッグしやすくなります。最短で、console.error(err);とも書きます。
同期処理と非同期処理の違い
APIを使うためには、非同期処理の理解が必須です。JavaScriptでは、命令は基本的に「上から順番に実行される(同期処理)」ように動きます。しかし、外部のデータを取りに行く処理(API通信など)はすぐには終わらないことが多いため、非同期処理(ひどうきしょり)として扱われます。
同期処理とは?
- 上から順に、1つずつ命令を実行
- 前の処理が終わるまで次に進めない
console.log("A");
console.log("B"); // ← AのあとにすぐBが出る
非同期処理とは?
- 時間がかかる処理(API通信など)を「あとで」実行
- JavaScriptは他の処理を止めずに先へ進める
- 結果が返ってきたら、あらためてその処理を行う
なぜ非同期が必要なの?
- APIからデータを取るのは1〜2秒かかることもある
- その間に画面が止まると、ユーザーにとって不便
- JavaScriptは「他のことをやりながら待つ」しくみを持っている
非同期を扱うための書き方
JavaScriptでは、非同期処理を扱うために以下のような書き方があります:
.then()を使った方法(Promiseチェーン)・・・軽量なAPIasync / awaitを使った方法(読みやすく実務向け)・・・時間がかかりそうなもの
非同期にする理由は「ユーザー体験を止めないため」順番を守るために .then() や await を使います
| 種類 | 処理の流れ | 特徴 |
|---|---|---|
| 同期処理 | 完全に終わってから次へ進む | 安定だけど遅いと画面が止まる |
| 非同期処理 | 結果を待たずに次に進む | 画面が止まらないが順番は保証されない |
| 非同期+制御 | .then() や await で順番を指定 | 順番が必要なときに便利 |
APIとは?
Application Programming Interface(アプリケーション プログラミング インターフェース)
の略です。簡単にいうと、他のサービスにお願いして、情報やデータをもらうためのしくみです。
- API = 自動販売機(欲しいデータをリクエスト → データが返ってくる)
- fetch() = ボタンを押す動作(商品を選ぶ)
- JSON = 出てきた缶ジュース(形式化されたデータ)
の3つを使います。
JSONとは?
JSON(ジェイソン)とは、JavaScript Object Notation(ジャバスクリプト オブジェクト表記)の略で、データをやり取りするときの「決まった形(ルール)」です。
- 文字列(テキスト)として受け取られる
- JavaScriptの
.json()で中身をオブジェクトとして使える形に変換できる - 配列(リスト)と組み合わせることで、たくさんのデータもやり取り可能
The Cat API(無料・認証不要でも使える)のエンドポイント
「猫の画像を表示したい!」と思ったとき、自分で画像を用意しなくても、
猫画像を配っているサイト(=API)にお願いすれば、代わりに送ってくれます。
https://api.thecatapi.com/v1/images/search
このURLにアクセスすると、ランダムな猫の画像が1枚返されます。
レスポンスはこんな感じのJSON
[
{
"id": "abc",
"url": "https://cdn2.thecatapi.com/images/abc.jpg",
"width": 800,
"height": 600
}
]
上記のJsonファイルの中の "url" を取り出して画像を表示することができたりします。
const imgUrl = data[0].url;
無料で使えるトランプ画像APIのエンドポイント
ランダムなトランプ1枚の画像URLを返してくれるAPI
https://deckofcardsapi.com/api/deck/new/draw/?count=1
レスポンスはこんな感じのJSONです
{
"cards": [
{
"value": "7",
"suit": "HEARTS",
"image": "https://deckofcardsapi.com/static/img/7H.png"
}
],
...
}
JavaScriptステップアップトレーニング
APIで取得したトランプのカードを表示させます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>トランプカードを表示しよう</title>
</head>
<body>
<h1>ランダムなトランプカード</h1>
<p><button id="draw-btn">カードを引く</button></p>
<div id="card-area">
<!-- カード画像と情報が表示されます -->
</div>
<script>
const btn = document.getElementById('draw-btn');
const cardArea = document.getElementById('card-area');
btn.addEventListener('click', () => {
fetch('https://deckofcardsapi.com/api/deck/new/draw/?count=1')
.then(res => res.json())
.then(data => {
console.log(JSON.stringify(data, null, 2));
const card = data.cards[0];
const image = card.image;
const value = card.value;
const suit = card.suit;
cardArea.innerHTML = `
<p>${suit}の${value} </p>
<img src="${image}" alt="カード画像" width="200">
`;
})
.catch(err => {
cardArea.textContent = 'カードの取得に失敗しました。';
console.error(err);
});
});
</script>
</body>
</html>
ここまでで .then() を使ったAPI通信の基本が理解できました!
次は、非同期処理をより見やすく書ける async / await の書き方を学びましょう。
トランプカードをさらに応用!ハイアンドローゲームの作成
APIで取得したカードを使ってハイアンドローを作成してみましょう。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>ハイアンドローゲーム</title>
<style>
.area {
display: flex;
gap: 30px;
}
</style>
</head>
<body>
<h1>ハイアンドローに挑戦!</h1>
<div id="game-area">
<div class="area">
<div>
<p>あなたのカード</p>
<div id="player-card"></div>
</div>
<div>
<p>相手のカード:</p>
<div id="opponent-card"></div>
</div>
</div>
<p>
<button id="high-btn" disabled>HIGH(高い)</button>
<button id="low-btn" disabled>LOW(低い)</button>
</p>
<p id="result"></p>
<p><button id="start-btn">ゲームスタート</button></p>
</div>
<script>
const startBtn = document.getElementById('start-btn');
const highBtn = document.getElementById('high-btn');
const lowBtn = document.getElementById('low-btn');
const playerCardDiv = document.getElementById('player-card');
const opponentCardDiv = document.getElementById('opponent-card');
const resultP = document.getElementById('result');
let playerValue = 0; // プレイヤーのカードの数値
// カードのvalueを数値に変換
function getCardValue(value) {
if (value === 'ACE') return 1;
if (value === 'JACK') return 11;
if (value === 'QUEEN') return 12;
if (value === 'KING') return 13;
return Number(value);
}
// 最初のカードを引く(あなたのカード)
function drawPlayerCard() {
fetch('https://deckofcardsapi.com/api/deck/new/draw/?count=1')
.then(res => res.json())
.then(data => {
const card = data.cards[0];
playerValue = getCardValue(card.value);
playerCardDiv.innerHTML = `<img src="${card.image}" alt="${card.value} of ${card.suit}" width="100">`;
resultP.textContent = '';
opponentCardDiv.innerHTML = '';
highBtn.disabled = false;
lowBtn.disabled = false;
});
}
// 次のカードを引いて結果判定
function drawOpponentCard(guess) {
fetch('https://deckofcardsapi.com/api/deck/new/draw/?count=1')
.then(res => res.json())
.then(data => {
const card = data.cards[0];
const opponentValue = getCardValue(card.value);
opponentCardDiv.innerHTML = `<img src="${card.image}" alt="${card.value} of ${card.suit}" width="100">`;
// 判定
if (
(guess === 'high' && opponentValue > playerValue) ||
(guess === 'low' && opponentValue < playerValue)
) {
resultP.textContent = 'あなたの勝ち!';
} else if (opponentValue === playerValue) {
resultP.textContent = '引き分け(ノーカウント)';
} else {
resultP.textContent = 'あなたの負け';
}
highBtn.disabled = true;
lowBtn.disabled = true;
});
}
// イベント設定
startBtn.addEventListener('click', drawPlayerCard);
highBtn.addEventListener('click', () => drawOpponentCard('high'));
lowBtn.addEventListener('click', () => drawOpponentCard('low'));
</script>
</body>
</html>
その他のAPI
| 種類 | API名 | 内容・できること | 利用形態 | 備考 |
|---|---|---|---|---|
| 絵文字 | Emoji API(emoji-api.com など) | Unicode絵文字の一覧、カテゴリ、コードなどを取得 | 無料 | 教材にも遊びにも使える |
| 国情報 | REST Countries API | 各国の国名・首都・通貨・国旗・人口など | 無料 | 表・検索・一覧表示の教材に向く |
| GitHub | GitHub REST API | ユーザー・リポジトリ・スター数などの情報 | 無料(要APIキー) | ポートフォリオと組み合わせるのも可 |
| NASA | NASA Open API | 宇宙画像、火星探査データ、天体写真など | 無料(APIキー必要) | 天体系教材・英語APIの練習にも |
| 音楽情報 | iTunes Search API | 曲名・アーティスト・アルバム画像など | 無料 | 音楽再生ではなく情報取得専用 |
| 天気(別) | WeatherAPI / OpenWeatherMap | 詳細な天気、週間予報、天気アイコンなど | 無料〜有料 | 学習利用は無料枠で十分 |
| 地図検索 | Mapbox API | 地図の表示・経路探索・ピン立て | 有料(無料枠あり) | Google Mapsの代替として人気 |
商品検索・EC系API 一覧
| 種類 | API名 | 内容・できること | 利用形態 | 備考 |
|---|---|---|---|---|
| 商品検索 | Amazon PA-API | 商品の画像・価格・説明・レビューなど | 無料(制限あり) | Amazonアソシエイト登録が必須。紹介実績が必要。 |
| 商品検索 | Rakuten Ichiba API | 楽天市場の商品一覧・価格・画像など | 無料 | APIキー取得のみで利用可能。学習にも使いやすい。 |
| 商品検索 | Yahoo! Shopping API | 商品検索・ランキング・画像・価格など | 無料(要申請) | Yahooデベロッパー登録が必要 |
