Skip to content

Instantly share code, notes, and snippets.

@kobitoDevelopment
Last active February 2, 2026 13:11
Show Gist options
  • Select an option

  • Save kobitoDevelopment/6bdb33c71342375d644fa6fc60af4578 to your computer and use it in GitHub Desktop.

Select an option

Save kobitoDevelopment/6bdb33c71342375d644fa6fc60af4578 to your computer and use it in GitHub Desktop.

ブラウザが自動で実施するケース

  • GET、POST、HEAD 以外のメソッド(PUT、DELETE など)
  • カスタムヘッダーを含む(Authorization、X-Custom-Header など)
  • Content-Type が application/json など

実行順序

  1. ブラウザがOPTIONSメソッドでプリフライトリクエストを送る
  2. サーバーが許可情報(許可するオリジン・メソッド・ヘッダー)を返す
  3. ブラウザが許可情報を検証し、本番リクエストが許可されているか判断する
  4. 許可されていれば、ブラウザが本番リクエストを送る
  5. サーバーがリクエストを処理する
  6. サーバーがレスポンスを返す
  7. ブラウザがレスポンスを受け取り、JavaScriptに結果が返る

送信側の構成要素

const response = await fetch('http://localhost:8080/api/users', {
  method: 'OPTIONS',  // プリフライトは必ずOPTIONSメソッド
  headers: {
    'Origin': 'http://localhost:3000',           // このオリジンからリクエストする
    'Access-Control-Request-Method': 'DELETE',   // 実際のリクエストではDELETEメソッドを使うことを申告
    'Access-Control-Request-Headers': 'Authorization',  // 実際のリクエストではAuthorizationヘッダーを送ることを申告
  },
});

受信側の制御

<?php
// 許可するオリジン
$allowedOrigins = [
    'http://localhost:3000',
    'https://example.com',
];

// 許可するメソッド
$allowedMethods = ['GET', 'POST'];  // DELETEやPUTは許可しない

// 許可するヘッダー
$allowedHeaders = ['Content-Type'];  // Authorizationは許可しない

// リクエスト元のオリジンを取得
$origin = $_SERVER['HTTP_ORIGIN'] ?? '';

// オリジンが許可リストにあるかチェック
if (in_array($origin, $allowedOrigins)) {
    header("Access-Control-Allow-Origin: $origin");
}

// プリフライトリクエストの処理
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    header("Access-Control-Allow-Methods: " . implode(', ', $allowedMethods));
    header("Access-Control-Allow-Headers: " . implode(', ', $allowedHeaders));
    header("Access-Control-Max-Age: 86400");
    http_response_code(204);
    exit;
}

// 以下、通常のAPI処理
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment