CORSとは?

Cross-Origin Resource Sharing(CORS)は、Webページがそのページを提供したドメインとは異なるドメインへのリクエストを制限するブラウザのセキュリティメカニズムです。フロントエンド(例:https://myapp.com)が異なるドメイン(例:https://api.example.com)にAPI呼び出しを行うと、ブラウザはまずサーバーがそれを明示的に許可しているかどうかを確認します。

サーバーのレスポンスに適切なAccess-Control-Allow-Originヘッダーが含まれていない場合、ブラウザはリクエストをブロックし、CORSエラーをスローします。重要なのは、CORSはブラウザによって適用されるということです。リクエスト自体はサーバーに到達しますが、ブラウザがJavaScriptによるレスポンスの読み取りを防止します。

よくあるCORSエラー

  • 'Access-Control-Allow-Origin'ヘッダーがない:サーバーのレスポンスにCORSヘッダーが完全に欠けています。修正方法:サーバーのレスポンスにヘッダーを追加してください。
  • プリフライトリクエストが通過しない:カスタムヘッダーや非シンプルメソッド(PUT、DELETE)を使用するリクエストの場合、ブラウザはOPTIONSプリフライトリクエストを送信します。サーバーはこれに正しく応答する必要があります。
  • クレデンシャルフラグ:withCredentials: trueでCookieやAuthorizationヘッダーを使用する場合、サーバーはAccess-Control-Allow-Credentials: trueを返す必要があり、オリジンは具体的に指定する必要があります(*は使用できません)。
  • 許可ヘッダーの不一致:リクエストにAccess-Control-Allow-Headersに記載されていないヘッダーが含まれている場合、プリフライトは失敗します。

フレームワーク別のCORS修正方法

上のツールを使用して、バックエンドに合わせた正確な修正コードを生成できます。すべてのフレームワークに共通する基本原則は同じです:サーバーが適切なAccess-Control-Allow-*ヘッダーを返すように設定します。本番環境では、特に認証付きリクエストを扱う場合、ワイルドカード(*)の代わりに、許可するオリジンを正確に指定してください。

CORSプリフライトメカニズムの理解

ブラウザが「シンプル」でない(基本的なヘッダーを持つGET/POST以外の)クロスオリジンリクエストを行う場合、まずOPTIONSプリフライトリクエストを送信してサーバーに許可を求めます。この2段階のプロセスがCORSの混乱の大部分の原因です。

プリフライトリクエストのトリガー

  • カスタムヘッダー:Accept、Content-Type(シンプルな値の場合)、Content-Language以外のヘッダーはプリフライトをトリガーします。よくあるトリガー:AuthorizationX-Requested-WithX-API-Key
  • シンプルでないメソッド:PUT、DELETE、PATCHはすべてプリフライトをトリガーします。GETとフォームデータを使用したPOSTはトリガーしません。
  • シンプルな値を超えるContent-Type:application/jsonはプリフライトをトリガーしますが、application/x-www-form-urlencodedはトリガーしません。JSONボディを使用したfetchが、同じエンドポイントでフォームデータでは機能する理由です。

CORSデバッグチェックリスト

CORSエラーに遭遇した場合、以下のチェックリストを順番に確認してください:

  • 1. ブラウザコンソールを確認:エラーメッセージが、どのヘッダーが欠落または設定ミスしているかを正確に教えてくれます
  • 2. OPTIONSレスポンスを検査:DevTools→ネットワークタブ→失敗したリクエストでフィルター→OPTIONSレスポンスに正しいAccess-Control-Allow-OriginAccess-Control-Allow-MethodsAccess-Control-Allow-Headersが含まれているか確認
  • 3. オリジンが正確に一致するか確認:http://localhost:3000http://localhost:3001は異なるオリジンです。末尾のスラッシュも重要です。
  • 4. クレデンシャルモードを確認:クッキーを送信する場合、サーバーはAccess-Control-Allow-Credentials: trueで応答する必要があり、Allow-Originにワイルドカード(*)は使用できません
  • 5. プロキシがヘッダーを除去していないか確認:リバースプロキシ(Nginx、Cloudflare、AWS ALB)がCORSヘッダーを除去またはオーバーライドすることがあります

本番環境でよくあるCORSの間違い

最も頻繁な本番環境のCORS問題には、クレデンシャルでAccess-Control-Allow-Origin: *を使用すること(これはサイレントに失敗します)、サーバーレス関数(Lambda、Vercel)でOPTIONSリクエストの処理を忘れること、Allow-Originヘッダーを動的に設定する際にVary: Originを含めないこと(CDNキャッシュの問題を引き起こす)があります。もう一つのよくある間違いは、開発環境でCORSを修正しても、ヘッダーを除去する異なるプロキシ設定でデプロイすることです。

CORSに関するよくある質問

CORSエラーの原因は何ですか?

CORSエラーは、サーバーのレスポンスにAccess-Control-Allow-Originヘッダーがないため、ブラウザがクロスオリジンリクエストをブロックしたときに発生します。ブラウザは同一オリジンポリシーを適用しており、異なるドメイン、ポート、またはプロトコルからのリクエストはCORSプリフライトチェックをトリガーします。重要なのは、CORSはブラウザのみで適用されるということです。リクエスト自体はサーバーに到達しますが、ブラウザがJavaScriptによるレスポンスの読み取りを防止します。

Express.jsでCORSを修正するにはどうすればよいですか?

corsパッケージをインストールし(npm install cors)、すべてのオリジンを許可するにはapp.use(cors())を追加するか、正確なオリジンを指定します:app.use(cors({ origin: 'https://yourdomain.com' }))。CookieやAuthorizationヘッダーを使用するリクエストの場合は、credentials: trueを設定し、ワイルドカード(*)を許可オリジンとして使用しないでください。正確なドメインを指定する必要があります。

CORSプリフライトリクエストとは何ですか?

プリフライトは、カスタムヘッダーや非シンプルHTTPメソッド(PUT、DELETE、PATCH)を使用するクロスオリジンリクエストの前に、ブラウザが自動的に送信するHTTP OPTIONSリクエストです。サーバーはAccess-Control-Allow-MethodsAccess-Control-Allow-Headersヘッダーに加えて、200または204ステータスでOPTIONSに応答する必要があります。プリフライトが失敗すると、実際のリクエストは送信されません。

なぜPostmanでは動作するのにブラウザでは動作しないのですか?

CORSはブラウザのセキュリティメカニズムであり、サーバー間通信やPostman、curl、RESTクライアントなどのツールには適用されません。Postmanは同一オリジンポリシーを適用せずにリクエストを直接送信するため、リクエストは成功します。ブラウザでは、サーバーがCORSヘッダーを通じて明示的に許可しない限り、JavaScriptはクロスオリジンレスポンスの読み取りが制限されます。

関連する開発者ツール