ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
| この記事の要点 |
|---|
|
fetch API での基本
// JSON 送信
async function postJson(data) {
const response = await fetch("/api/users", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-TOKEN": document.querySelector('meta[name="csrf-token"]').content,
"Accept": "application/json"
},
body: JSON.stringify(data)
});
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
return await response.json();
}
// 使用
postJson({ name: "Alice", email: "alice@example.com" })
.then(result => console.log(result))
.catch(error => console.error(error));
FormData(ファイル送信)
async function uploadFile(file) {
const formData = new FormData();
formData.append("file", file);
formData.append("description", "ファイル説明");
const response = await fetch("/api/upload", {
method: "POST",
headers: {
"X-CSRF-TOKEN": csrfToken
// ⚠️ Content-Type は指定しない (FormData が自動でセット)
},
body: formData
});
return await response.json();
}
// HTML
document.getElementById("fileInput").addEventListener("change", (e) => {
uploadFile(e.target.files[0]);
});
axios での書き方
// 基本的な設定
axios.defaults.headers.common["X-CSRF-TOKEN"] =
document.querySelector('meta[name="csrf-token"]').content;
axios.defaults.headers.common["Accept"] = "application/json";
// POST (JSON)
try {
const response = await axios.post("/api/users", {
name: "Alice",
email: "alice@example.com"
});
console.log(response.data);
} catch (error) {
if (error.response) {
// サーバ応答 (4xx, 5xx)
console.error("Status:", error.response.status);
console.error("Data:", error.response.data);
} else if (error.request) {
// ネットワークエラー
console.error("No response");
} else {
console.error("Error:", error.message);
}
}
// FormData (ファイル含む)
const formData = new FormData();
formData.append("file", fileInput.files[0]);
await axios.post("/api/upload", formData);
// axios も Content-Type を自動セット
jQuery での書き方
// $.ajax
$.ajaxSetup({
headers: {
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
}
});
// JSON 送信
$.ajax({
url: "/api/users",
method: "POST",
contentType: "application/json",
data: JSON.stringify({ name: "Alice", email: "alice@example.com" }),
dataType: "json",
success: (data) => console.log(data),
error: (xhr, status, error) => console.error(error)
});
// $.post (簡略形)
$.post("/api/users", { name: "Alice" })
.done(data => console.log(data))
.fail((xhr) => console.error(xhr.statusText));
CSRF トークン送信
Laravel
// HTML head に meta タグ
// JS で読み取り
const csrfToken = document.querySelector('meta[name="csrf-token"]').content;
// fetch
fetch("/api/users", {
method: "POST",
headers: { "X-CSRF-TOKEN": csrfToken, "Content-Type": "application/json" },
body: JSON.stringify(data)
});
// axios はメタタグから自動読込
Spring Security
// thymeleaf テンプレート
// JS
const csrfToken = document.querySelector('meta[name="_csrf"]').content;
const csrfHeader = document.querySelector('meta[name="_csrf_header"]').content;
fetch("/api/users", {
method: "POST",
headers: { [csrfHeader]: csrfToken, "Content-Type": "application/json" },
body: JSON.stringify(data)
});
CORS (クロスオリジン)
// 別ドメインへの POST
fetch("https://api.example.com/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
credentials: "include" // Cookie 送信
});
// サーバ側 (Laravel)
// config/cors.php
'paths' => ['api/*'],
'allowed_origins' => ['https://myapp.example.com'],
'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE'],
'allowed_headers' => ['*'],
'supports_credentials' => true,
// Spring Boot
@CrossOrigin(origins = "https://myapp.example.com", allowCredentials = "true")
@RestController
public class UserController { }
エラーハンドリング
// fetch では HTTP エラーは reject しない
async function postUser(data) {
try {
const response = await fetch("/api/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
});
// HTTP エラー判定 (自動では throw しない)
if (!response.ok) {
const errorData = await response.json().catch(() => ({}));
throw new Error(errorData.message || `HTTP ${response.status}`);
}
return await response.json();
} catch (error) {
if (error.name === "TypeError" && error.message.includes("Failed to fetch")) {
// ネットワークエラー
alert("ネットワークエラー: 接続を確認してください");
} else {
// HTTP エラー or その他
alert(`エラー: ${error.message}`);
}
throw error;
}
}
タイムアウト設定
// fetch + AbortController
async function postWithTimeout(url, data, timeoutMs = 10000) {
const controller = new AbortController();
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
try {
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
signal: controller.signal
});
clearTimeout(timeoutId);
return await response.json();
} catch (error) {
clearTimeout(timeoutId);
if (error.name === "AbortError") {
throw new Error("タイムアウト");
}
throw error;
}
}
// axios
axios.post("/api/users", data, { timeout: 10000 })
リトライ機構
async function postWithRetry(url, data, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const response = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data)
});
if (response.ok) return await response.json();
// 5xx の場合のみリトライ (4xx はクライアントエラー、リトライ無意味)
if (response.status < 500) {
throw new Error(`HTTP ${response.status}`);
}
} catch (error) {
if (i === maxRetries - 1) throw error;
// 指数バックオフ
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
}
}
}
ローディング表示・二重送信防止
let isSubmitting = false;
document.getElementById("submit-btn").addEventListener("click", async () => {
if (isSubmitting) return; // 二重送信防止
isSubmitting = true;
const btn = document.getElementById("submit-btn");
btn.disabled = true;
btn.textContent = "送信中...";
try {
const result = await postUser({ name: "Alice" });
alert("成功");
} catch (error) {
alert("エラー: " + error.message);
} finally {
isSubmitting = false;
btn.disabled = false;
btn.textContent = "送信";
}
});
よくあるトラブル
- 419 Page Expired: CSRF トークン不正
- 422 Unprocessable Entity: バリデーションエラー
- CORS エラー: 別ドメイン + サーバ側 CORS 未設定
- Mixed Content: HTTPS ページから HTTP API
- Content-Type 違い: JSON vs form-data の指定ミス
- Cookie 送信されない:
credentials: "include"必要
関連記事
ページの作成
親となるページを選択してください。
親ページに紐づくページを子ページといいます。
例: 親=スポーツ, 子1=サッカー, 子2=野球
子ページを親ページとして更に子ページを作成することも可能です。
例: 親=サッカー, 子=サッカーのルール
親ページはいつでも変更することが可能なのでとりあえず作ってみましょう!
子ページ
子ページはありません
同階層のページ
- インストールと設定
- クイックスタート & チュートリアル(初心者向け)
- クイックスタート & チュートリアル(中級者向け)
- ルーティング
- Bladeテンプレート(ビュー/レイアウト)
- コントローラー
- マイグレーションとテーブル定義
- データベースの設定
- Eloquentモデル (ORM)
- SQLとクエリビルダー
- バリデーション
- .envファイルの設定値へのアクセス
- 動作環境による分岐処理
- configフォルダ配下の設定値へのアクセス
- assetヘルパーを利用したpublicフォルダへのアクセス
- storageフォルダへのアクセス
- アプリケーション名の変更
- メンテナンス
- ログイン画面(認証システム)の作成
- ログインの必須化
- ログインユーザー情報の取得
- ルートの認証化
- 本番サーバーへのデプロイ方法
- 多言語化
- csrf_field
- ファイルのダウンロード
- CSVのアップロードおよび読み込み(maatwebsite/excel)
- ページタイトルの設定
- コマンド一覧
- エラー一覧
- SQLの実行ログ出力方法
- キャッシュのクリア
- Selectの結果の最初もしくは最後に任意の値を追加する方法
- ajaxでPOST通信する際の注意点
- ソーシャルログインの実装
- セッション情報の確認
- ログイン、ユーザー登録、パスワードリセット後のリダイレクト先の変更方法
- redirectやreturn viewにメッセージを付与する方法
- クッキー(cookie)の設定と取得
- クラスの再読み込み
- csrfの有効時間を変更する方法
- ViewComposerを用いてviewに共通の値を付与する方法
- View::shareを用いて共通の値を各ビューに渡す方法
- ミドルウェアを用いた処理の共通化
- Middleware内でAuth::check()などを使用する方法
- Controller以外でリダイレクトする方法
- セッションの値の取得/保存/更新/削除
- $requestの値を変更する方法
- 常時SSL化
- ページング(ページネーション)をする方法
- vue.jsとの連携
- Vue.jsと連携するSPA実行環境構築
- .envの値をvue.jsで参照する方法
- vue.jsを本番環境にリリースする方法
- could not find driver(Windows, MySQL編)
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript base URL 取得方法|window.location.origin と SSR/Node.js 対応
- 4 YouTube Data API v3 エラー一覧|403/400/404 の主要原因と切り分け
- 5 Spring Frameworkのアノテーション一覧
- 6 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 7 3Dグラフィックスとは|モデリング/レンダリング/主要ソフトウェア (Blender / Maya)
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Laravel キャッシュクリア完全ガイド(cache:clear / config:clear / 2026-05-18 07:42:07
- プロジェクトの作成と削除 2026-05-18 07:42:07
- インストール直後にNetbeansが反応しない 2026-05-18 07:42:07
- 動画やチャンネルの検索 2026-05-18 07:42:07
- APIキー取得方法 2026-05-18 07:42:07
- チャンネル情報の取得 2026-05-18 07:42:07
- API 入門 — Web API(REST / GraphQL / gRPC / 2026-05-18 07:42:07
- インストール(eclipseプラグイン) 2026-05-18 07:42:07
- Laravel「Dotenv values containing spaces must be surrounded 2026-05-18 07:42:07
- エラー一覧 2026-05-18 07:42:07
- curl: (51) SSL: certificate subject name '~' does not match 2026-05-18 07:42:07
- インストール方法(Windows版) 2026-05-18 07:42:07
- JSONから配列に変換 2026-05-18 07:42:07
- 処理を一定時間待つ 2026-05-18 07:42:07
- A non well formed numeric value encountered 2026-05-18 07:42:07
コメントを削除してもよろしいでしょうか?