CORSとは:プリフライト、ヘッダー、CORSエラーの解決方法

CORS解説

CORSとは:プリフライト、ヘッダー、エラーと解決方法 | We.Inc

CORSの仕組みを解説。シンプルリクエストとプリフライトの違い、すべてのAccess-Controlヘッダー、認証情報のルール、よくあるコンソールエラー、Express・Next.js・nginxでのサーバー側の修正方法を紹介します。

CORS(オリジン間リソース共有)は、別オリジンのJavaScriptがレスポンスを読み取ってよいことを、サーバーがブラウザーに伝える仕組みです。サーバーはAccess-Control-Allow-Originと関連ヘッダーで応答します。それ以外のメソッド、カスタムヘッダー、JSONボディを使うリクエストは、先にOPTIONSのプリフライトを送ります。修正は常に呼び出し先のサーバー側で行い、ページ側では行いません。

CORSレスポンスヘッダーの一覧

CORSエラーはコードが壊れているように見えますが、実際にはリクエストはたいていサーバーに問題なく届いています。ブラウザーが応答をスクリプトに渡すのを拒否しただけです。下のシミュレーターでリクエストとサーバーの設定を指定すると、プリフライトが発生するか、ブラウザーがレスポンスを通すか、どのコンソールメッセージが表示されるかがわかります。

よくある質問

ブラウザーでは失敗するのに、Postmanやcurlでは動くのはなぜですか?

CORSはブラウザーだけが適用する仕組みで、あるサイトのスクリプトがあなたのCookieを使って別のサイトのデータを読むのを防ぎます。curlのようなツールは信頼できないページのコードを実行していないので、CORSを無視します。サーバーのレスポンスは同じで、ブラウザーだけがそれを渡さないと判断したのです。

プリフライトリクエストが発生する条件は何ですか?

GET、HEAD、POST以外のメソッド、安全とされる少数のヘッダー(Accept、Accept-Language、Content-Language、Content-Type、Range)以外のヘッダー、またはフォームエンコード、multipart、text/plain以外のContent-Typeです。最もよくある原因はapplication/jsonの送信です。

フロントエンドでCORSを解決できますか?

できません。リクエストにAccess-Controlヘッダーを付けても効果はなく、mode: no-corsではスクリプトが読めない不透明なレスポンスが返ります。APIにヘッダーを追加してもらうか、自分のサーバーでデータを取得して中継するかのどちらかです。

CookieとAccess-Control-Allow-Origin: * を一緒に使えますか?

使えません。リクエストが認証情報を含む場合、ブラウザーはワイルドカードのオリジンを拒否し、正確なオリジンとAccess-Control-Allow-Credentials: trueを求めます。メソッド、ヘッダー、公開ヘッダーのリストでのワイルドカードも同様です。

スクリプトでカスタムレスポンスヘッダーを読めないのはなぜですか?

クロスオリジンのスクリプトは、デフォルトでは安全なレスポンスヘッダーの短いリストしか見られません。それ以外のヘッダー(たとえばX-Request-Id)をAccess-Control-Expose-Headersに列挙すると、読み取れるようになります。

同一オリジンと、ブラウザーが読み取りをブロックする理由

シンプルリクエストとプリフライト

コンソールエラーの読み方

よくあるCORSエラーとその解決方法

メッセージの文言はブラウザーによって異なります。以下はMDNでFirefoxが示す理由で、Chromeは同じ内容をより長い文で表示します。

CORSのコンソール上の理由とサーバー側の修正

サーバー用スニペット

Express:認証情報付きの許可リスト

オリジンがリストにある場合だけそれを返し、プリフライトには204で応答し、Varyを追加してキャッシュがオリジンを区別できるようにします。

Next.jsのルートハンドラー

Cookieを使わない公開エンドポイントならワイルドカードを使えます。OPTIONSをエクスポートして、プリフライトに専用の応答を返します。

APIの前段に置いたnginx

alwaysフラグでエラーレスポンスにもヘッダーが付くので、500でもCORSエラーではなく本来のステータスが表示されます。

ブラウザー側:クロスオリジンでCookieを送る

credentials: "include" を指定すると、サーバー側でより厳しい認証情報のルールが有効になります。

CORSリクエストシミュレーター

リクエストとサーバーのCORSヘッダーを指定すると、プリフライトが送られるか、ブラウザーがスクリプトにレスポンスの読み取りを許すかがわかります。

リクエスト

サーバーの応答

ページのオリジン

APIのオリジン

メソッド

Content-Type

ボディなし

追加のリクエストヘッダー(なしの場合は空欄)

Cookieを送信(credentials: include)

Access-Control-Allow-Origin

Access-Control-Allow-Methods

Access-Control-Allow-Headers

Access-Control-Allow-Credentials: true

判定

同一オリジン:CORSは適用されず、レスポンスを読み取れます。

プリフライトなし:これはシンプルリクエストです。

プリフライトが必要:ブラウザーは先にOPTIONSを送ります。

理由:メソッドがGET、HEAD、POSTのいずれでもありません。

理由:ヘッダー {v} は安全リストに含まれていません。

理由:Content-Type {v} は3つのシンプルな型のいずれでもありません。

許可:スクリプトはレスポンスを読み取れます。

ブロック。コンソール上の理由:

サーバーが送るべきヘッダー

無料で始める · クレジットカード不要

関連: ガイド|Webマーケティングと集客を学ぶ

製品

ご利用いただける方

機能

リソース

会社情報

サイトマップを見る