テクノロジー · 実用ガイド

ブラウザーのCORSエラーを切り分ける:プリフライト、実レスポンス、Origin契約

API呼び出し前、OPTIONS成功後、または資格情報付きの場合で失敗点は異なります。ヘッダーを推測する前に、Networkパネルの証拠で停止箇所を特定します。

OPTIONS、Origin、Allow、Actualの段階を示すオリジナルCORS要求チェーン図。
オリジナルイラスト:プリフライトと実レスポンスを別々に確認します。 Watch at Ease

curlやPostmanが成功しても、ブラウザーのJavaScriptがCORSエラーになる場合は、1件の要求ではなく要求チェーンとして調べます。プリフライト、実レスポンス、資格情報と正確なOriginを別々に確認します。

ブラウザーの要求チェーンを記録する

開発者ツールのNetworkでログを保持し、失敗を1回だけ再現します。OPTIONSが送信されたか、実要求だけか、サーバー到達前に止まったかを判断します。curlやPostmanの成功はHTTP到達性を示すだけで、ブラウザーがクロスオリジン応答をスクリプトへ公開する証明ではありません。

OPTIONSを独立した交換として調べる

OPTIONSがあれば、要求と応答を分けて確認します。要求には通常Origin、Access-Control-Request-Method、必要ならAccess-Control-Request-Headersが入ります。応答は正確なOrigin、メソッド、要求ヘッダーを許可する必要があり、リダイレクト、認証要求、ネットワーク障害、許可ヘッダー不足は実要求を止めます。

実レスポンスも別に調べる

プリフライト成功は実要求の送信を許可するだけです。401、404、500でも、JavaScriptから読むには実レスポンスに一致する許可Originが必要です。本文は読めるのに独自ヘッダーが見えない場合は、プリフライトではなくAccess-Control-Expose-Headersを確認します。

資格情報とOrigin契約を証明する

CookieやHTTP認証を含む場合、Access-Control-Allow-Origin: * は使えません。正確な要求OriginとAccess-Control-Allow-Credentials: trueが必要です。プリフライト自体には資格情報がないため、OPTIONSに認証を要求するミドルウェアは実要求前にチェーンを遮断します。CORSはSameSiteや第三者Cookie制限を上書きしません。

動的Origin、キャッシュ、順序を確認する

許可Originを動的に返すならVary: Originを付け、共有キャッシュの誤再利用を防ぎます。CORSミドルウェアがOPTIONSとエラー経路にも実行されることを確認します。ローカル設定ではなく、配備済みサービスのNetwork結果を検証します。

停止分岐表を使う

OPTIONSも実要求もなければURL、混合コンテンツ、拡張機能、DNSなどを調べます。OPTIONSだけならプリフライト、両方あるのに読めなければ実レスポンス、本文だけ読めて独自ヘッダーが隠れるなら必要な応答ヘッダーの公開を修正します。

資格情報、ワイルドカード、正確なOrigin、Vary Originを比較するオリジナル図。
オリジナルイラスト:資格情報付き要求には正確な許可Originが必要です。 Watch at Ease