最終更新
リンドくん
たなべ先生、APIを作ってフロントエンドから呼び出そうとしたら「CORSエラー」って出たんですけど...これって何ですか?
たなべ
あぁ、Web開発では誰もが一度は遭遇する壁だね!
CORSはセキュリティのための仕組みなんだけど、正しく理解していないと開発の大きな障害になっちゃうんだ。今日はその仕組みと対処法をしっかり学んでいこう。
Web開発を始めたばかりの方が、必ずと言っていいほど遭遇するのが「CORSエラー」です。
フロントエンドからバックエンドのAPIを呼び出そうとしたとき、ブラウザのコンソールに赤いエラーメッセージが表示され、途方に暮れた経験はないでしょうか?
このエラーメッセージ、見たことありますよね。
実はこれ、ブラウザがあなたのWebアプリケーションを守ろうとしている証なんです。
本記事では、CORSとプリフライトリクエストの基本から、よくある落とし穴とその解決法まで、初心者の方でも理解できるよう詳しく解説していきます。
この知識は、モダンなWeb開発では必須のスキルです。ぜひ最後まで読んで、CORSを味方につけてください!
HackATAは、エンジニアを目指す方のためのプログラミング学習コーチングサービスです。 経験豊富な現役エンジニアがあなたの学習をサポートします。
✓ 質問し放題
✓ β版公開中(2025年内の特別割引)
リンドくん
そもそもCORSって何の略なんですか?なんでこんな面倒な仕組みがあるんでしょう...
たなべ
CORSはCross-Origin Resource Sharing(オリジン間リソース共有)の略なんだ。
実はこれ、Webをより安全にするためのセキュリティ機能なんだよ。歴史から見ていこうか。
CORSを理解するには、まずSame-Origin Policy(同一オリジンポリシー)という概念を知る必要があります。
これはブラウザに組み込まれた基本的なセキュリティ機能で、異なるオリジン(origin)からのリソースへのアクセスを制限するものです。
「オリジン」とは、以下の3つの要素の組み合わせで決まります。
例えば、以下のURLを見てみましょう。
この場合のオリジンは https://____.com:443 です。
もしSame-Origin Policyがなかったらどうなるでしょうか?
悪意のあるWebサイトが、あなたのログイン情報を使って銀行のサイトにアクセスし、勝手に送金してしまう...そんなことが可能になってしまいます。
具体的なシナリオを見てみましょう。
https://A.com)にログインしているhttps://B.com)を開いてしまうhttps://A.comのAPIを呼び出そうとするこのように、Same-Origin Policyはユーザーを守るための重要な防御壁なのです。
しかし現代のWeb開発では、異なるオリジン間での通信が必要なケースが多々あります。
そこで登場するのがCORSです。
CORSはサーバー側が明示的に許可した場合のみ、異なるオリジンからのアクセスを許可する仕組みです。
つまり、Same-Origin Policyという厳格なルールに対して、サーバーが「このオリジンからのアクセスは信頼できるから許可します」と宣言できるのがCORSなのです。
リンドくん
じゃあ、具体的にどうやってCORSを設定すればいいんですか?
たなべ
基本的にはHTTPレスポンスヘッダにいくつかの情報を追加するだけなんだ。
でも、その設定を間違えるとセキュリティの穴になっちゃうから注意が必要だよ。
CORSを有効にするための最も基本的なヘッダは Access-Control-Allow-Origin です。
このヘッダを設定することで、指定したオリジン(この例では https://frontend.____.com)からのリクエストを許可できます。
CORS設定で使用される主要なヘッダは以下の通りです。
以下は、よくある実用的なCORS設定の例です。
初心者がやりがちな危険な設定があります。
この設定は絶対にやってはいけません。
ワイルドカード(*)ですべてのオリジンを許可しつつ、クレデンシャル(認証情報)も許可しているため、どんなサイトからでもあなたのAPIにアクセスできてしまいます。
正しくは、以下のどちらかを選択すべきです。
リンドくん
先生、ネットワークタブを見たら、1回のリクエストのつもりが2回送られてるんですけど...バグですか?
たなべ
それはバグじゃなくてプリフライトリクエストだよ!
ブラウザが本番のリクエストを送る前に「このリクエスト送っても大丈夫?」って事前確認してるんだ。
プリフライトリクエストは、特定の条件を満たすクロスオリジンリクエストの前に、ブラウザが自動的に送信するOPTIONSメソッドのリクエストです。
これは「本番のリクエストを送っても安全か」をサーバーに確認するための仕組みです。
すべてのクロスオリジンリクエストでプリフライトが発生するわけではありません。
以下のような「単純リクエスト(Simple Request)」以外の場合に発生します。
プリフライトが発生しない単純リクエストの条件
application/x-www-form-urlencodedmultipart/form-datatext/plainプリフライトが発生するケース
このリクエストは以下の理由でプリフライトが発生します。
application/json実際のHTTP通信を見てみましょう。
プリフライトが成功して初めて、本番のPUTリクエストが送信されます。
多くの初心者が陥る問題は、OPTIONSメソッドに対するレスポンスを返していないことです。
この実装では、プリフライトリクエスト(OPTIONSメソッド)が来たときに適切なレスポンスを返せません。
プリフライトリクエストは毎回送信されると、パフォーマンスに影響します。
Access-Control-Max-Ageヘッダで適切にキャッシュしましょう。
開発時はlocalhostでテストするため、以下のような設定をしがちです。
本番環境にデプロイすると、オリジンが変わるため動かなくなります。
環境変数を使って設定を切り替えましょう。
CORS設定を行う際は、以下の点を必ず確認してください。
CORSエラーをデバッグする際は、以下の手順で確認しましょう。
特に重要なのは、プリフライトリクエスト(OPTIONS)と本番リクエスト(GET/POSTなど)の両方のレスポンスヘッダを確認することです。
リンドくん
CORSって最初は面倒だなと思ってましたけど、セキュリティのために大事な仕組みなんですね!
たなべ
その通り!最初は戸惑うかもしれないけど、仕組みを理解すれば怖くないんだ。
むしろ、適切なCORS設定はユーザーを守るための大切なスキルだからね。
CORS(Cross-Origin Resource Sharing)とプリフライトリクエストは、Web開発において避けて通れない重要な概念です。
今回学んだ内容を整理しましょう。
重要ポイントをおさらいしましょう。
CORSは最初は難しく感じるかもしれませんが、一度理解してしまえば、セキュアなWeb開発の強い味方になります。
エラーに遭遇したときは、落ち着いてエラーメッセージを読み、設定を見直してみて下さい。