fetch は、JavaScriptでHTTPリクエストを行うための標準的な方法であり、APIとの通信に非常に便利です。これを使うことで、非同期処理を簡潔に記述することができます。このエッセイでは、fetchの基本的な使い方から、エラーハンドリングやレスポンス処理の詳細までをカバーします。
1. fetch の基本
fetch は、主に外部リソースを取得するために使用されます。HTTPリクエストを送信し、そのレスポンスを非同期で処理するためのAPIです。基本的な構文は次のようになります。
javascriptfetch(url)
.then(response => {
// レスポンスが正常かを確認
if (!response.ok) {
throw new Error('ネットワークのエラー');
}
return response.json(); // JSON形式のレスポンスを解析
})
.then(data => {
console.log(data); // レスポンスのデータを利用
})
.catch(error => {
console.error('エラー:', error);
});
このコードでは、指定したURLに対してGETリクエストを送り、サーバーから返されるレスポンスを処理します。response.okは、ステータスコードが200番台であればtrueを返します。エラーが発生した場合は、throwを使ってエラーハンドリングを行っています。
2. HTTPメソッドを指定する
fetchの最も基本的な使用法は、GETリクエストを送ることですが、POST、PUT、DELETEなど、他のHTTPメソッドにも対応しています。これらを使うためには、fetchの第二引数にオプションを指定します。
POSTリクエスト
POSTリクエストは、サーバーにデータを送信するために使われます。例えば、フォームのデータを送信する場合などです。
javascriptfetch('https://example.com/api/data', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'John Doe',
age: 30
})
})
.then(response => response.json())
.then(data => {
console.log('サーバーからのレスポンス:', data);
})
.catch(error => {
console.error('エラー:', error);
});
上記の例では、methodをPOSTに設定し、bodyには送信するデータをJSON形式で指定しています。ヘッダーのContent-Typeは、送信するデータがJSON形式であることを示します。
PUTリクエスト
PUTリクエストは、既存のリソースを更新するために使用されます。POSTと同様に、methodにPUTを指定し、更新するデータをbodyで送信します。
javascriptfetch('https://example.com/api/data/1', {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'John Updated',
age: 31
})
})
.then(response => response.json())
.then(data => {
console.log('更新後のデータ:', data);
})
.catch(error => {
console.error('エラー:', error);
});
3. fetch と非同期処理
fetchは非同期関数であり、Promiseを返します。これにより、非同期処理の結果をthenメソッドを使って処理できます。しかし、async/awaitを使用すると、より直感的で読みやすいコードを書くことができます。
async/awaitを使った例
javascriptasync function fetchData() {
try {
const response = await fetch('https://example.com/api/data');
if (!response.ok) {
throw new Error('ネットワークのエラー');
}
const data = await response.json();
console.log(data);
} catch (error) {
console.error('エラー:', error);
}
}
fetchData();
async関数内では、awaitを使用してfetchの結果を待つことができ、コードが同期的に実行されるように見せることができます。これにより、非同期の操作をより直感的に書くことができます。
4. エラーハンドリング
fetchには内蔵のエラーハンドリング機能がありますが、fetch自体がネットワークエラーやサーバーエラーを直接的に検出することはありません。たとえば、HTTPステータスが404や500の場合でも、fetchは正常にresponseオブジェクトを返します。そのため、ステータスコードを手動で確認する必要があります。
javascriptfetch('https://example.com/api/data')
.then(response => {
if (!response.ok) {
throw new Error(`HTTPエラー! ステータス: ${response.status}`);
}
return response.json();
})
.then(data => {
console.log('データ:', data);
})
.catch(error => {
console.error('エラー:', error);
});
このコードでは、response.okを使ってレスポンスが成功かどうかを確認し、エラーがあれば適切に処理します。
5. レスポンスの処理方法
fetchのレスポンスは、通常、JSON形式で返されますが、text(), blob(), arrayBuffer()など、他の形式にも変換できます。以下は、異なる形式でレスポンスを処理する方法です。
テキスト形式でレスポンスを取得
javascriptfetch('https://example.com/textfile.txt')
.then(response => response.text())
.then(text => {
console.log('テキストデータ:', text);
})
.catch(error => {
console.error('エラー:', error);
});
Blob形式でレスポンスを取得(画像やバイナリデータ)
javascriptfetch('https://example.com/image.jpg')
.then(response => response.blob())
.then(blob => {
const img = document.createElement('img');
img.src = URL.createObjectURL(blob);
document.body.appendChild(img);
})
.catch(error => {
console.error('エラー:', error);
});
6. fetch の制限と注意点
-
CORSポリシー: サーバーがCORS (Cross-Origin Resource Sharing) をサポートしていない場合、
fetchリクエストはブロックされることがあります。クロスオリジンリクエストには、サーバー側で適切なCORSヘッダーが設定されている必要があります。 -
タイムアウト処理:
fetchにはタイムアウト機能が組み込まれていません。タイムアウトを設定するには、AbortControllerを使用することが一般的です。
タイムアウトの例
javascriptconst controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), 5000); // 5秒後にタイムアウト
fetch('https://example.com/api/data', {
signal: controller.signal
})
.then(response => response.json())
.then(data => {
clearTimeout(timeoutId); // タイムアウトを解除
console.log(data);
})
.catch(error => {
if (error.name === 'AbortError') {
console.error('リクエストはタイムアウトしました');
} else {
console.error('エラー:', error);
}
});
7. まとめ
fetchは、JavaScriptで外部リソースと通信するための非常に強力で柔軟なツールです。基本的なGETリクエストから、POSTやPUTリクエストを通じてデータを送信する方法まで、さまざまな機能を提供しています。非同期処理のためのPromiseやasync/awaitと組み合わせることで、簡潔で読みやすいコードが書けるようになります。また、エラーハンドリングやレスポンスの種類に応じた処理を適切に行うことが重要です。
