CORS インスペクター
CORS 診断パネル
サーバー側でプリフライトリクエストと実際のリクエストをシミュレートし、Access-Control-Allow-Origin、Access-Control-Allow-Headers、credentials の問題をすばやく特定します。
サーバー側でCORSプリフライトと実リクエストを忠実にシミュレートし、6つのレスポンスヘッダーを項目ごとにチェック。クロスオリジン設定エラーを正確に特定し、Nginx/Node.js/Springなどマルチフレームワークの修正コードを提供します。
関連おすすめ
ユースケース
- ブラウザコンソールにNo 'Access-Control-Allow-Origin' headerエラーが表示された場合、すぐに本ツールで対象APIが実際に返すCORSヘッダーを検出
- フロントエンド・バックエンド分離プロジェクトの連携段階で、バックエンドのCORS設定が正しく有効かどうかを検証し、盲目的に設定を変更して時間を無駄にすることを回避
- Nginx、ApacheリバースプロキシまたはAPIゲートウェイ(Kong/APISIX/Spring Cloud Gateway)設定後、CORSルールが正しく転送されているかを検証
- Cookieを含むクロスオリジンリクエストが失敗した場合、クレデンシャルモードに切り替えてAllow-CredentialsとAllow-Originの設定競合を検出
- カスタムリクエストヘッダー(X-Token、X-Requested-Withなど)追加後にリクエストがブロックされた場合、Allow-Headersで正しく宣言されているかをチェック
- PUT/DELETE/PATCHなど非単純メソッドのリクエストがクロスオリジンで失敗した場合、Allow-Methodsに対応するメソッドが含まれているかをチェック
- フロントエンドがカスタムレスポンスヘッダー(X-Request-Id、X-Total-Countなど)を読み取れない場合、Access-Control-Expose-Headers設定を検出
- CDNアクセラレーション後にクロスオリジンが不安定になった場合、CDNが誤ったレスポンスをキャッシュしないようVary: Originが正しく設定されているかをチェック
- 本番環境で断続的にクロスオリジンエラーが発生する場合、問題シナリオを再現し完全なレスポンスメッセージを保存してバックエンドの調査に供する
- CORSの原理を学習する際に、実際のリクエストを通じて各レスポンスヘッダーの働きを観察し、クロスオリジンメカニズムへの理解を深める
使い方
- ターゲットURL入力欄に検査したいエンドポイントの完全なアドレスを入力します(http/https対応、パスが必要です)
- リクエストOriginにフロントエンドページの実際のオリジンを入力します(例:https://example.com。プロトコルとポートを含め、パスは含めないでください)
- HTTPリクエストメソッドを選択します(GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS)、デフォルトはGET
- カスタムリクエストヘッダー領域に送信する必要のあるヘッダーを追加します。1行に1つ、X-Token: abc123のような形式で。Content-Typeがapplication/jsonなど非単純タイプの場合は自動的にプリフライトがトリガーされます
- シナリオに応じて「クレデンシャルを送信」オプションをチェックします。フロントエンドコードでwithCredentials=trueまたはfetchのcredentials: 'include'を使用している場合は必ずチェックしてください
- 「検査開始」ボタンをクリックすると、ツールはサーバー側でOPTIONSプリフライトリクエストと(プリフライトが通過するかプリフライトが不要な場合は)実リクエストを順次送信します
- 分析レポートを確認:まず全体評価結果を見て、次に各CORSヘッダーのステータスを項目ごとにチェックし、赤色のエラー項目の修正提案に基づいてサーバー設定を調整し、修正後に再検出して検証してください
特徴
- サーバー側でプリフライトリクエストと実リクエストを忠実にシミュレート。ブラウザキャッシュや拡張機能の影響を受けず、より正確な結果
- OPTIONSプリフライトレスポンスと実際のGET/POSTレスポンスを分離して表示し、どの段階で問題が発生しているかを明確に特定
- 6つのコアCORSレスポンスヘッダーを項目別に検査:Access-Control-Allow-Origin、Allow-Methods、Allow-Headers、Allow-Credentials、Expose-Headers、Max-Age。各ヘッダーごとに合格/警告/失敗ステータスを表示
- ワイルドカード*とクレデンシャルモードの古典的な競合をインテリジェントに検出し、最も一般的な設定の落とし穴を即座に警告
- カスタムリクエストOrigin、HTTPメソッド(GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS)、任意のカスタムリクエストヘッダーをサポート
- クレデンシャル(Cookie/Authorizationヘッダー/TLSクライアント証明書)を含めるかどうかを切り替え可能、withCredentials=trueシナリオをシミュレート
- Vary: Originレスポンスヘッダーが正しく設定されているかを自動検出し、CDN/リバースプロキシが誤ったCORSレスポンスをキャッシュする問題を防止
- プリフライトキャッシュMax-Age設定を構造化表示し、プリフライトリクエスト頻度がパフォーマンスに与える影響を評価
- Access-Control-Expose-Headers設定をチェックし、フロントエンドJavaScriptが読み取り可能なレスポンスヘッダーを確認
- Nginx、Apache、Node.js/Express、Spring Boot、Python/Django/Flaskなど主流サーバーフレームワークの設定例を含む詳細な修正提案を行ごとに提供
- ステータスコード、すべてのレスポンスヘッダー、レスポンスボディプレビューを含む完全なリクエスト/レスポンス生メッセージを記録し、詳細なトラブルシューティングに対応
- 単純リクエストとプリフライトが必要なリクエストの違いを自動的に識別し、なぜそのリクエストがOPTIONSプリフライトをトリガーしたかを説明
- リダイレクトシナリオでのCORS問題を検出(301/302/307/308リダイレクト後にOriginが変化するかどうか)
- HTTPS/HTTP混合コンテンツシナリオの検出をサポートし、混合コンテンツによって引き起こされるクロスオリジン関連の問題を警告
よくある質問
Postman/curlでAPIにリクエストしても問題ないのに、ブラウザでアクセスするとすぐにクロスオリジンエラーが出るのはなぜですか?
これは最も古典的なCORSの問題です!なぜならPostmanとcurlはブラウザの同一オリジンポリシーの制限をまったく受けないからです——それらはHTTPクライアントでありブラウザではないため、レスポンスをインターセプトせず、OPTIONSプリフライトリクエストも自動的に送信しません。クロスオリジンエラーはブラウザ固有のセキュリティメカニズムであり、ブラウザのJavaScriptランタイム環境でのみCORSチェックが実行されます。Postmanで通信できることは、エンドポイント自体がデータを返せることを証明するだけで、CORS設定が正しいことを証明するものではありません。ブラウザ、または本ツール(サーバー側でブラウザのCORSフローをシミュレート)を使用して検出する必要があり、そうすれば問題が明らかになります。
CORSエラーはフロントエンドの問題ですかバックエンドの問題ですか?誰が修正すべきですか?
CORSエラーの99%はバックエンドの設定問題(またはNginx/ゲートウェイ層の設定問題)であり、フロントエンドにできることは非常に限られています。CORSの核心は、サーバーがレスポンスヘッダーを通じて「クロスオリジンアクセスを許可する」ようブラウザに「権限を与える」ことです。フロントエンドはwithCredentialsの設定やリクエストヘッダーの設定程度しかできず、ブラウザのセキュリティ制限をバイパスすることはできません。ネットでよく言われるフロントエンドでプロキシを使う方法(devServer proxy、NginxリバースプロキシでフロントエンドとAPIを同じオリジンにプロキシ)は、本質的にはブラウザを「だまして」同一オリジンリクエストだと思う せているだけで、CORS問題を真に解決しているわけではありません。本番環境でフロントエンドとバックエンドが異なるオリジンの場合は、依然としてバックエンドが正しくCORSを設定する必要があります。
なぜGETリクエストはクロスオリジンエラーにならないのに、POST/PUTに変えるとクロスオリジンエラーになるのですか?
GETは通常単純リクエストの条件を満たすため、ブラウザが直接リクエストを送信するからです;一方POSTでContent-Type: application/json(POSTエンドポイントの90%がこれ)を送信すると、単純リクエストではなくなりOPTIONSプリフライトがトリガーされます。プリフライトではサーバーが正しいCORSヘッダーを返す必要があります。多くの人がGET/POSTにだけCORSヘッダーを設定してOPTIONSメソッドを処理していなかったり、OPTIONSレスポンスにヘッダーがなかったりしてエラーが発生します。PUT/DELETE/PATCHメソッド自体が単純メソッドではないため、必然的にプリフライトがトリガーされます。
開発環境ではクロスオリジンをどう解決すればよいですか?本番環境では?
開発環境にはいくつかの方法があります:①フレームワーク組み込みのプロキシ(Vue CLIのdevServer.proxy、Viteのserver.proxy、Create React Appのproxy):APIリクエストをフロントエンド開発サーバーと同じオリジンにプロキシし、ブラウザが同一オリジンだと思い込ませてクロスオリジンを発生させない;②ブラウザのセキュリティパラメータを無効にする(Chromeの起動パラメータに--disable-web-securityを追加するなど)、ローカルでの一時的なテスト専用で、通常のブラウジングには絶対に使用しない;③バックエンドでlocalhostオリジンを許可するCORS設定を行う(推奨、本番環境の動作と一貫性があります)。本番環境ではバックエンドがCORSを正しく設定する必要があります:許可するオリジンホワイトリストの設定、Allow-Methods/Allow-Headers/Allow-Credentialsの正しい設定、Vary: Originの追加、またはゲートウェイ/NginxでCORSを一元的に処理します。
Access-Control-Allow-Originは複数のオリジンを設定できますか?複数ドメインでクロスオリジンを許可するにはどうすればよいですか?
できません。Access-Control-Allow-Originレスポンスヘッダーは1つの値しか持てません——具体的なオリジン(https://a.comなど)か*のいずれかです。ブラウザは複数のオリジンを受け付けません(例えばhttps://a.com,https://b.comと書いても無効で、ブラウザは不一致とみなします)。正しい複数オリジンの設定方法は:サーバーが許可するオリジンのホワイトリストを維持し、リクエストを受け取るたびにリクエストヘッダーのOrigin値を読み取り、そのOriginがホワイトリストにあるかどうかをチェックし、あればAccess-Control-Allow-Originをその具体的なOrigin値に設定し、同時にVary: Originヘッダーを返します;なければCORSヘッダーを返さないかエラーを返します。複数のAllow-Originヘッダーを返したり、複数の値をカンマ区切りで返そうとしたりしないでください——ブラウザはどちらも認識しません。
OPTIONSプリフライトリクエストはビジネスロジックを返す必要がありますか?直接204を返してもよいですか?
OPTIONSプリフライトリクエストはビジネスロジックやレスポンスボディを返す必要はなく——正しいCORSレスポンスヘッダーと200/204ステータスコードを返すだけで十分です。ブラウザは正しいCORSヘッダーを受け取ればプリフライトが通過したとみなし、OPTIONSレスポンスのbodyコンテンツを読み取りません。そのためベストプラクティスは:Nginx/ゲートウェイ層でOPTIONSリクエストを直接インターセプトし、204 No Contentと正しいCORSヘッダーを返してバックエンドアプリケーションサーバーに転送しないことです——これによりバックエンドの負荷が軽減されるだけでなく、バックエンドがOPTIONSをサポートしていないことによる405エラーも回避できます。ただし、OPTIONSレスポンスのCORSヘッダーが実リクエストのCORSヘッダーと一致していることを確認してください。
withCredentials: trueを設定したのにCookieが送信されないのはなぜですか?
Cookie付きクロスオリジンリクエストには3つの条件を同時に満たす必要があります:①フロントエンドXMLHttpRequest.withCredentials = trueまたはfetchのcredentials: 'include';②バックエンドレスポンスヘッダーAccess-Control-Allow-Credentials: true;③Access-Control-Allow-Originが*ではなく具体的なオリジンであること。3つすべてが必要です。さらにCookieの属性に注意してください:Cookieがクロスオリジンリクエストで送信されるにはSameSite=None; Secure(HTTPS環境)が設定されている必要があります;CookieがSameSite=LaxまたはStrictの場合、クロスオリジンリクエストでは送信されません;CookieのDomain属性が正しく設定されている必要があります;サードパーティCookieポリシーの影響にもご注意ください(ChromeなどのブラウザはサードパーティCookieに制限があります)。
CORSとCSRFはどのような関係ですか?CORSを設定するとCSRF脆弱性につながりますか?
CORSはクロスオリジンアクセス制限を緩和するものであり、CSRFはクロスサイトリクエストフォージェリ攻撃です——両者は異なる概念です。正しく設定されたCORSが直接CSRF脆弱性を引き起こすことはありません——なぜならCORSはJSがレスポンスを読み取ることを許可するだけであり、CSRFは攻撃者がユーザーに知らないうちにリクエストを送信させるもので(imgタグ、自動送信フォームなど)、これらのリクエストはCORSがなくてもCookie付きで送信されるからです。CSRFを防御するにはCSRFトークン、SameSite Cookie、Origin/Referer検証などの方法が必要であり、CORSを無効にしてCSRFを防ぐことはできません。ただし、CORS設定でAllow-Originを*に設定しクレデンシャルを許可すると、実際にCSRFリスクが増大するため、クレデンシャルを使用するシナリオでは絶対に*を使用せず、ホワイトリストのオリジンを厳格に制限する必要があります。
ファイルダウンロード、リダイレクト、画像/scriptタグの読み込みでCORSの問題は発生しますか?
通常の<img>、<script>、<link>タグによるクロスオリジンリソースの読み込み(CDN画像、JSスクリプト、CSS)はデフォルトでCORSの問題はありません——これらは「埋め込みリソース」であり「AJAXリクエスト」ではないため、ブラウザは読み込みを許可しますがJSはコンテンツを読み取れません。ただし、Canvasでクロスオリジン画像を操作したり、これらのリソースをfetch/XHRで読み込んでコンテンツを読み取ったりする場合はCORSが必要であり、タグにcrossorigin属性を追加する必要があります。クロスオリジンファイルダウンロード(aタグクリックでのダウンロード)もデフォルトでCORSを必要としません。リダイレクトはCORSに影響します:OPTIONSプリフライトリクエストが3xxリダイレクトを返すとブラウザは直接拒否します(Preflight redirect is not allowed);実リクエストのリダイレクトがクロス ginの場合、各ホップが正しくCORSヘッダーを返す必要があります。
NginxでCORSを正しく設定するにはどうすればよいですか?動作する設定例を教えてください
Nginx推奨設定のポイント:①mapディレクティブを使用してOriginホワイトリストにマッチさせ、$cors_origin変数を動的に設定;②OPTIONSリクエストはバックエンドに転送せず直接204を返す;③add_headerはエラーレスポンスにもヘッダーが含まれるようalwaysパラメータを追加することを忘れない;④Vary: Originを追加;⑤Allow-Methods/Allow-Headers/Credentialsを正しく設定。設定例は本ツールの検出結果の修正提案に記載されています。Nginx、Apache、Node.js Express、Spring Boot、Python Flask/Django、Koa、Go Ginなどの主流フレームワークについて、検証済みの設定スニペットを提供しています。
CORSを設定した後、有効になっているかどうかをどのように検証すればよいですか?
CORS検証の手順:①まず本ツールでオンライン検出を行い、URL、Origin、メソッド、ヘッダー、クレデンシャルオプションを入力し、プリフライトと実リクエストの各チェックがパスするか確認;②ブラウザDevToolsのNetworkパネルを開き、Disable cacheにチェックを入れ(古いキャッシュの干渉を避ける)、クロス ginリクエストをトリガーし、OPTIONSプリフライトと実リクエストのレスポンスヘッダーが正しいか検査;③ConsoleにCORS関連のエラーがないか確認;④さまざまなシナリオをテスト:カスタムヘッダーなしのGETリクエスト、application/json付きのPOSTリクエスト、PUT/DELETEメソッド、Cookieあり/なし、カスタムヘッダーあり;⑤curlでOPTIONSリクエストをシミュレート:curl -i -X OPTIONS -H "Origin: https://yoursource.com" https://api.example.com/endpointを実行し、レスポンスヘッダーが正しいか確認。
なぜChromeではクロス ginリクエストがエラーになるのにSafari/Firefoxでは正常に動作するのですか?またはその逆は?
ブラウザによってCORS仕様の実装の詳細には違いがあります:①SafariはプリフライトキャッシュMax-Ageの制限がより厳しく(初期バージョンでは600秒しかありませんでした)、Cookieポリシー(ITPインテリジェントトラッキング防止)もより厳格であり、クロス gin Cookieの問題が発生する可能性があります;②Chromeはクレデンシャル付きのワイルドカードチェックがより厳格で、Allow-Headers/Allow-Methodsも*を許可しませんが、Firefoxの一部のバージョンはより緩い場合があります;③古いIE(IE11)は標準のXMLHttpRequestではなくXDomainRequestを使用しており、CORSの実装には多くの落とし穴があります(カスタムヘッダーをサポートせず、GET/POSTのみをサポート);④Varyヘッダーの処理、リダイレクト処理、セキュリティヘッダーの処理にはブラウザ間で微妙な違いがあります。解決方法はCORS仕様に厳密に従って設定し、特定のブラウザの互換性のある動作に依存しないことです。
Access-Control-Max-Ageはどのくらいの値が適切ですか?長すぎたり短すぎたりするとどのような問題がありますか?
3600(1時間)から86400(24時間)の間に設定することを推奨します。短く設定しすぎた場合(60秒など):プリフライトキャッシュがすぐに期限切れになり、頻繁にOPTIONSリクエストが送信され、リクエストのレイテンシーとサーバーの負荷が増加します。モバイルの弱いネットワーク環境では影響が顕著です。長く設定しすぎた場合(31536000、つまり1年など):CORS設定を更新した場合(許可するメソッド、ヘッダーを追加した場合など)、ユーザーのブラウザにキャッシュされた古いプリフライト結果が期限切れになるまで長時間かかり、その間設定が有効にならない問題が発生する可能性があります。またChromeとFirefoxは86400秒を超える値を自動的に86400秒に制限するため、それ以上長く設定しても効果はありません。開発環境では-1を設定してプリフライトキャッシュを無効にし、デバッグしやすくできます。
WebSocket接続にはクロス ginの問題がありますか?CORSはWebSocketに適用されますか?
WebSocket(ws://およびwss://)はHTTP CORSメカニズムの制限を受けません。WebSocketは独立したプロトコルであり、HTTP AJAXリクエストではないからです。ただしWebSocketのハンドシェイクフェーズはHTTPリクエストであり、サーバーはOriginヘッダーをチェックして接続を許可するかどうかを決定できます——これはWebSocketレベルの権限制御であり、標準CORSではありませんが原理は似ています。WebSocket接続が拒否された場合は、HTTP CORSヘッダーではなくWebSocketサーバー側のOrigin検証設定を確認する必要があります。Socket.IOなどのライブラリは独自のクロス gin設定方法を持っている場合があり、標準CORS設定と似ていますが完全に同一ではありません。また、HTTP/2 Server Push、WebRTCなどの他のブラウザAPIにも独自の権限制御があり、HTTP CORSに完全には従いません。
本ツールの検出結果はブラウザの動作と一致しますか?ツールのチェックはパスしたのにブラウザでまだエラーが出るのはなぜですか?
本ツールはサーバー側でW3C CORS仕様に厳密に従ってブラウザのプリフライトと実リクエストフローをシミュレートしており、CORSヘッダーのチェックロジックはモダンブラウザと基本的に一致しています。ツールがパスしたのにブラウザでまだエラーが発生する場合、考えられる原因:①ブラウザが古いプリフライト結果またはレスポンスをキャッシュしている——Ctrl+F5でハードリフレッシュするかキャッシュをクリアして再試行;②ブラウザ拡張機能(広告ブロッカー、プライバシー保護、セキュリティプラグイン)がリクエストを変更またはインターセプトした;③ツールに入力したOrigin、リクエストヘッダー、メソッド、クレデンシャルオプションが実際のフロントエンドの送信内容と一致しない(フロントエンドが実際にはツールに追加していないカスタムヘッダーを送信しているなど);④CDN/プロキシノードのキャッシュに一貫性がなく、ツールがリクエストしたノードとブラウザがリクエストしたノードが異なる結果を返す;⑤ブラウザに特別なセキュリティポリシーがある(HTTPSページがHTTP混合コンテンツをリクエストしてブロックされた、ローカルファイルfile://プロトコルの特別な制限など)。
トラブルシューティング
ブラウザコンソールでNo 'Access-Control-Allow-Origin' headerエラーが報告されるが、curl/postmanでリクエストするとレスポンスヘッダーが見える
サーバーがOPTIONSメソッドにCORSヘッダーを設定していない:curlが送信するのはGET/POSTでヘッダーが見えるが、ブラウザはまずOPTIONSプリフライトを送信し、OPTIONSレスポンスにヘッダーがない サーバーが4xx/5xxエラーを返すときにCORSヘッダーを含めない:Nginxのadd_headerはデフォルトで2xxと一部 の3xxにのみ有効であり、エラーレスポンスにはalwaysパラメータが必要 リクエストがWAF/ファイアウォール/セキュリティプラグインによってOPTIONSメソッドでブロックされ、ブロックレスポンスにCORSヘッダーがない CDNが古いヘッダーなしレスポンスをキャッシュした(Vary: Originの欠落によるキャッシュ汚染) ブラウザ拡張機能(広告ブロッカー、プライバシー保護プラグイン)がクロスオリジンリクエストヘッダーを変更またはインターセプトした
Access-Control-Allow-Origin: *を設定したが、Cookie付きリクエストがまだエラーになる
これはCORS仕様の強制的な制限です:リクエストがクレデンシャルを含む(withCredentials: true、Cookie、HTTP認証)限り、Allow-Originは絶対にワイルドカード*にできません フロントエンドがwithCredentialsを明示的に設定していなくても、ターゲットドメインが現在のドメインとCookieを共有している場合、ブラウザが自動的に含める可能性があります Allow-Originだけでなく、部 分 のブラウザではクレデンシャル付きの場合Allow-HeadersとAllow-Methodsも*にできません Access-Control-Allow-Credentials: trueを同時に設定し、Allow-Originは*ではなく具体的なリクエストオリジンを返す必要があります
プリフライトOPTIONSリクエストが405 Method Not Allowedまたは404 Not Foundを返す
バックエンドフレームワークのルートがGET/POSTなどの業務メソッドのみ設定されており、OPTIONSメソッドを処理するルートがない Nginx設定のtry_filesディレクティブがOPTIONSリクエストをインターセプトし、バックエンドに転送せず直接404を返す APIゲートウェイまたはセキュリティグループの設定がOPTIONSメソッドを「無用 」なメソッドとしてブロックしている CORSサポートが有効になっていないSpring Bootなどのフレームワークは、OPTIONSリクエストを自動的に拒否し403を返します RESTful API設計でOPTIONSリクエストに個別のハンドラーが設定されていない
POST application/jsonリクエストで常にヘッダーが許可されていないとエラーになるが、Content-TypeはAllow-Headersに追加済み
スペルミス:Content-Typeの大文字小文字、ハイフンの書き間違い(ContentType、Content-typeなど。仕様では大文字小文字を区別しないはずですが、厳密にマッチングするサーバーでは問題になることがあります) GET/POSTのレスポンスにのみヘッダーを追加し、OPTIONSプリフライトレスポンスには追加していない。ブラウザが見るのはOPTIONSのヘッダーです Allow-Headersに列挙されているヘッダーが不完全:例えばフロントエンドがX-Requested-Withやその他のカスタムヘッダーも送信しているのにリストにない 値に余分なスペースがある:例えば"Content-Type, Authorization"と書いた(カンマ後のスペースは通常問題ありませんが、部 分 の古いブラウザではパースに問題が生じることがあります) Access-Control-Allow-Headersがプリフライトリクエストで問い合わせられたヘッダーのみを返し、サポートされているすべてのヘッダーを返していない(仕様上は許可されていますが、部 分 のシナリオで問題になることがあります)
クロスオリジン設定はローカルテストで正常に動作するが、CDN/Nginxにデプロイすると不安定になりランダムにエラーが発生する
Vary: Originレスポンスヘッダーがない!CDNはURLでキャッシュし、最初のリクエストのCORSヘッダーがキャッシュされ、後続の異なるOriginからのリクエストが誤ったキャッシュレスポンスを取得する CDNがOPTIONSプリフライトレスポンスもキャッシュするキャッシュルールを設定しており、バックエンドがCORS設定を更新した後もCDNは古いキャッシュを提供し続ける Nginxに複数層のadd_headerが設定されており、下層のCORSヘッダーが上層によって上書きされるかマージ時にエラーが発生する CDNのHTTPヘッダー最適化機能がAccess-Control-*ヘッダーを自動的に削除または上書きする HTTPS/HTTP混合コンテンツ:ページはHTTPSだがエンドポイントがHTTPであり、ブラウザが直接ブロックしCORSエラーのように見える CDNノードの設定に一貫性がなく、CORSヘッダーがあるノードとないノードがある
フロントエンドはレスポンスステータスコードとデータを取得できるが、カスタムレスポンスヘッダー(X-Total-Countなど)を読み取れない
Access-Control-Expose-Headersレスポンスヘッダーが設定されていない!CORS仕様ではデフォルトで少数の基本レスポンスヘッダーのみをJSの読み取り用に公開します デフォルトでアクセス可能なレスポンスヘッダーは:Cache-Control、Content-Language、Content-Length、Content-Type、Expires、Last-Modified、Pragmaのみです カスタムレスポンスヘッダー(X-Request-Id、X-Total-Count、Authorization、Set-Cookieなど)はExpose-Headersに列挙する必要があります Set-CookieとSet-Cookie2はフロントエンドJSに公開されることは決してありません——これはブラウザのセキュリティ制限であり、設定に関係なくブロックされます Expose-Headersに列挙されていても、Set-CookieはgetResponseHeaderで読み取ることができず、ブラウザによって自動的にフィルタリングされます
用語集
- CORS (Cross-Origin Resource Sharing)
- クロスオリジンリソース共有。W3C標準。HTTPヘッダーフィールドを追加することで、サーバーがどのオリジンからのリソースアクセスを許可するかを宣言できるようにします。モダンブラウザにおけるクロスオリジン問題の公式ソリューションです。
- 同一オリジンポリシー (Same-Origin Policy)
- ブラウザのコアセキュリティメカニズム。プロトコル、ドメイン、ポートの3つがすべて完全に同一の場合のみ同一オリジンとみなされ、異なるオリジンのJavaScriptはデフォルトで互いのリソースを読み取ることができません。
- プリフライトリクエスト (Preflight Request)
- 非単純クロスオリジンリクエストに対してブラウザが自動的に先送りするOPTIONSメソッドリクエスト。後続の実リクエストが許可されるかどうかをサーバーに問い合わせ、プリフライトが通過した後にのみ実リクエストを送信します。
- 単純リクエスト (Simple Request)
- 特定の条件(GET/HEAD/POSTメソッド、セーフリストヘッダーのみ、特定のContent-Type)を満たすクロスオリジンリクエスト。プリフライトを送信する必要がなく、直接実リクエストを送信します。
- Access-Control-Allow-Origin (ACAO)
- CORSのコアレスポンスヘッダー。リソースへのアクセスを許可するオリジンを指定します。具体的なオリジンURIまたはワイルドカード*を指定できますが、クレデンシャルを含む場合は*は使用できません。
- Access-Control-Allow-Methods (ACAM)
- プリフライトレスポンスヘッダー。サーバーがサポートするすべてのHTTPメソッドを列挙し、複数のメソッドはカンマで区切ります。
- Access-Control-Allow-Headers (ACAH)
- プリフライトレスポンスヘッダー。サーバーが許可するすべてのリクエストヘッダーフィールドを列挙します。フロントエンドがカスタムヘッダーを送信する場合はここで宣言する必要があります。
- Access-Control-Allow-Credentials (ACAC)
- レスポンスヘッダー。ブール値trueはクロスオリジンリクエストでCookie、Authorizationなどのクレデンシャルの送信を許可することを示します。これを設定する場合、Allow-Originは*にできません。
- Access-Control-Max-Age (ACMA)
- プリフライトレスポンスヘッダー。プリフライト結果のキャッシュ時間を秒単位で指定します。適切に設定するとOPTIONSリクエストが削減されパフォーマンスが向上します。
- Vary: Origin
- レスポンスヘッダー。CDN/プロキシに対してレスポンスコンテンツがOriginヘッダーに応じて変化することを伝えます。キャッシュ時にOriginをキャッシュキーの一部として含める必要があり、クロスオリジンレスポンスのキャッシュ不整合を防ぎます。
- CORSセーフリストリクエストヘッダー (CORS-safelisted request headers)
- Allow-Headersで宣言しなくても送信できるリクエストヘッダー。Accept、Accept-Language、Content-Language、Content-Type(特定の値)などが含まれます。
- 禁止ヘッダー名 (Forbidden header name)
- ブラウザがJavaScriptによるプログラム的な設定を禁止しているリクエストヘッダー。Host、Connection、Cookie、Originなどで、これらのヘッダーはブラウザによって自動的に制御されます。
- クレデンシャル付きリクエスト (Credentialed Request)
- Cookie、HTTP認証情報、TLSクライアント証明書などの身分証明情報を含むクロスオリジンリクエスト。フロントエンド・バックエンドでwithCredentialsとAllow-Credentialsを設定する必要があります。
- Access-Control-Expose-Headers
- レスポンスヘッダー。フロントエンドJavaScriptがアクセスできるレスポンスヘッダーを列挙します。デフォルトでは少数の基本ヘッダーのみアクセス可能で、カスタムレスポンスヘッダーはここで宣言する必要があります。
- OPTIONS メソッド
- HTTPメソッドの1つ。サーバーがサポートする通信オプションを取得するために使用されます。CORSはこれを使用してプリフライトリクエストを送信し、許可されるメソッド、ヘッダー、クレデンシャルなどを問い合わせます。
- Origin リクエストヘッダー
- ブラウザが自動的に追加するリクエストヘッダー。現在のリクエストがどのオリジン(プロトコル+ドメイン+ポート)から来ているかを示します。サーバーはこのヘッダーに基づいてクロスオリジンを許可するかどうかを判断します。
- crossorigin 属性
- HTML要素(script、img、linkなど)の属性。CORSを有効にしてリソースを読み込むかどうかを指定します。値はanonymous(クレデンシャルなし)とuse-credentials(クレデンシャルあり)です。
- no-cors リクエストモード
- fetch APIのモードの1つ。クロスオリジンリクエストの送信を許可しますが、単純リクエストのみ送信可能でJavaScriptはレスポンスコンテンツを読み取れません。不透明レスポンス(Opaque Response)の送信に相当します。
CORSレスポンスヘッダー完全対照表
| レスポンスヘッダー | 役割 | 値の例 | 注意事項 |
|---|---|---|---|
Access-Control-Allow-Origin | クロスオリジンアクセスを許可するオリジンを指定 | https://example.com または * | クレデンシャルを含む場合は絶対に*を使用できません。具体的なOriginを返す必要があります。動的に返す場合はVary: Originを追加する必要があります |
Access-Control-Allow-Methods | サーバーがサポートするすべてのHTTPメソッドを列挙 | GET, POST, PUT, DELETE, PATCH, OPTIONS | プリフライトレスポンスで必須。すべてのメソッドを列挙する必要があり、現在のリクエストメソッドだけではありません |
Access-Control-Allow-Headers | 許可されるすべてのリクエストヘッダーフィールドを列挙 | Content-Type, Authorization, X-Token | プリフライトリクエストにAccess-Control-Request-Headersがある場合は必須。カスタムヘッダーを含める必要があります。クレデンシャル付きの場合、一部 のブラウザでは*は使用できません |
Access-Control-Allow-Credentials | クレデンシャル(Cookieなど)を許可するかどうか | true | 小文字のtrueのみで、1やTrueは使用できません。trueを設定する場合、Allow-Originは*にできません |
Access-Control-Expose-Headers | JSが読み取り可能なレスポンスヘッダーを列挙 | X-Request-Id, X-Total-Count | デフォルトではCache-Control/Content-Language/Content-Type/Expires/Last-Modified/Pragmaのみ読み取り可能。カスタムヘッダーはここに列挙する必要があります |
Access-Control-Max-Age | プリフライト結果のキャッシュ時間(秒) | 3600 | Chrome/Firefoxの上限は86400秒(2時間)で、Safariはより短いです。値-1はキャッシュを無効にし毎回プリフライトを送信します |
Vary | CDN/プロキシにどのリクエストヘッダーがレスポンスに影響するかを伝える | Origin | Allow-Originを動的に返す場合はVary: Originを追加する必要があります。そうしないとCDNキャッシュによりクロスオリジンが不安定になります |
Access-Control-Request-Method | プリフライトリクエストヘッダー。実リクエストがどのメソッドを使用するかをサーバーに伝える | PUT | ブラウザがOPTIONSリクエストで自動的に送信し、フロントエンドが手動で設定する必要はありません |
Access-Control-Request-Headers | プリフライトリクエストヘッダー。実リクエストがどのヘッダーを含むかをサーバーに伝える | content-type, x-token | ブラウザがOPTIONSリクエストで自動的に送信し、複数ヘッダーはカンマ区切りです |
どのリクエストがプリフライトをトリガーするかの判定表
| トリガー条件 | プリフライトをトリガーするか | 詳細説明 |
|---|---|---|
| リクエストメソッドがGET/HEAD/POST以外(PUT/DELETE/PATCH/CONNECT/OPTIONS/TRACE) | はい | メソッドがこの3つでない限り、カスタムヘッダーがなくても常にプリフライトがトリガーされます |
| Content-Typeがtext/plain、multipart/form-data、application/x-www-form-urlencodedではない | はい | 最も一般的なのはapplication/jsonで、これは常にプリフライトをトリガーします!多くの開発者がこの落とし穴にはまります |
| リクエストにカスタムヘッダー(CORSセーフリストにないヘッダー)が含まれる | はい | X-Token、X-Requested-With、Authorization、X-Custom-Headerなどはすべてトリガーします |
| リクエストでReadableStreamをボディとして使用(ストリームアップロード) | はい | モダンブラウザのストリームアップロードAPIはプリフライトをトリガーします |
| XMLHttpRequest.uploadにイベントリスナーが登録されている(アップロード進捗のリスン) | はい | xhr.upload.onprogressを使用するとプリフライトがトリガーされます |
| リクエストメソッドがGET/HEAD/POSTで、Content-Typeが3つの単純タイプの1つであり、カスタムヘッダーがない | いいえ | これは単純リクエストであり、OPTIONSを送信せず直接送信されます |
| fetchのmodeを'no-cors'に設定 | CORSプリフライトは送信されないがレスポンスは不透明 | このモードではJSはレスポンスを読み取れず、単純リクエストのみ送信できます |
| fetchのcredentialsを'include'に設定しているが他の条件はすべて単純リクエスト | 場合による | credentials髪が直接プリフライトをトリガーするわけではありませんが、他のトリガー条件と組み合わさるとトリガーされます。クレデンシャル付きではCORS検証がより厳格になることに注意してください |
| 同じURLが比以前にプリフライトされMax-Ageキャッシュ時間内 | いいえ(キャッシュヒット) | キャッシュが無効になるか期限切れにならない限り、キャッシュ期間中はOPTIONSは再送信されません |
一般的なCORSエラーと解決策クイックリファレンス
| コンソールエラーメッセージ | 根本原因 | 解決策 |
|---|---|---|
| No 'Access-Control-Allow-Origin' header is present | レスポンスにCORSヘッダーがまったくない;サーバーがCORSを設定していない;ゲートウェイ/プロキシがヘッダーを削除した;500/404などのエラーレスポンスにヘッダーがない | サーバーのCORS設定を確認;Nginx add_headerにalwaysパラメータがあるか確認;OPTIONSリクエストが2xxを返しCORSヘッダーがあることを確認 |
| Allow-Origin値'XXX'が指定されたOriginと一致しない | Allow-Originに設定されたオリジンが実際のリクエストOriginと一致しない;設定ミス(余分なスラッシュ/ポートの誤り/httpとhttpsの混在) | Originホワイトリストにリクエスト元が含まれているか確認;末尾スラッシュがないことを確認;wwwと非wwwは異なるオリジンであることに注意;正しいOriginを動的に返す |
| プリフライトレスポンスがアクセス制御チェックに合格しない:HTTPステータスがokではない | OPTIONSリクエストが404/405/500などの非2xxステータスを返した;サーバールートがOPTIONSメソッドを処理していない;Nginx try_filesがOPTIONSをインターセプトした | OPTIONSリクエストが200/204を返すことを確認;サーバー/ゲートウェイ層でOPTIONSレスポンスを設定;NginxがOPTIONSを正しく処理することを確認 |
| メソッドXXXがAccess-Control-Allow-Methodsで許可されていない | プリフライトレスポンスのAllow-Methodsに使用しようとしているHTTPメソッドが含まれていない(例:PUTがリストにない) | Access-Control-Allow-Methodsにサポートが必要なすべてのメソッドをカンマ区切りで列挙 |
| リクエストヘッダーフィールドXXXがAccess-Control-Allow-Headersで許可されていない | カスタムヘッダーを送信したがAllow-Headersで宣言されていない;最も一般的なのはContent-Type: application/json、Authorizationの追加忘れ | Access-Control-Allow-Headersに使用するすべてのリクエストヘッダーを列挙(非単純タイプの場合はContent-Typeを含む) |
| クレデンシャルフラグがtrueの場合、Allow-Originはワイルドカード*にできない | クレデンシャル付きリクエスト(withCredentials=true)でサーバーがAllow-Origin: *を返した。これは仕様で明確に禁止されています | *は使用できません。リクエストOriginに基づいて具体的なオリジンを返す必要があります;同時にAllow-Credentials: trueを確認 |
| クレデンシャルフラグがtrueの場合、Allow-Headersはワイルドカード*にできない | クレデンシャル付きリクエストでAllow-Headersが*に設定されており、Chromeなどの一部ブラウザで許可されていない | 実際に使用するすべてのリクエストヘッダーを列挙し、*は使用しない |
| プリフライトリダイレクトは許可されていない | OPTIONSリクエストが3xxリダイレクトを返した。ブラウザはプリフライトリクエストのリダイレクトを追跡しません | OPTIONSリクエストが直接200を返し、リダイレクトしないことを確認;サーバー設定を修正しOPTIONSジャンプを回避 |
- 認証ヘッダー生成
- Cache-Control解析
- Content-Disposition解析
- CORSヘッダー生成
- CORS インスペクター
- CSP生成
- cURL コードジェネレーター
- DNS グローバル伝播チェック
- DNS参照
- Forwardedヘッダー解析
- hreflang生成
- HSTS解析
- HTTPクッキー解析ツール
- HTTPヘッダー検査
- HTTPリクエスト送信
- HTTPステータスコード検索
- IP アドレス検索
- IPv4 コンバーター
- IPv4範囲展開
- IPv6ツールボックス
- Linkヘッダー解析
- MX照会
- ポートチェック
- URLパラメータ生成
- レートリミットヘッダー解析
- リダイレクトチェッカー
- Robots.txt ジェネレーター
- robots.txt検査
- セキュリティヘッダー検査
- Security.txt ジェネレーター
- Set-Cookieパーサー
- サイトネットワーク監査
- Sitemap ジェネレーター
- Sitemap検査
- SSL証明書チェッカー
- サブネット計算機
- URL解析
- User-Agentパーサー
- UTMリンク生成
- WebSocketテスト
- 私のIPとは?
- WHOIS検索