CORS のエラーはなぜ起きますか。どう直しますか

同一オリジンの決まりと、ブラウザが応答を読ませずに止めることを説明し、直すのはサーバーの許可のヘッダーだと答える問い。プリフライトと Cookie の扱いまで話せると強い答えになります。

こう聞かれます

  • 「CORS のエラーが出たことはありますか。なぜ起きて、どう直しましたか」
  • 「同じ API を curl で呼ぶと動くのに、ブラウザの fetch だとエラーになります。なぜですか」
  • 「プリフライトとは何ですか」

面接官が見ている点

  • 止めているのはサーバーではなくブラウザだ、と分かっているか
  • 画面の側をいじって逃げるのではなく、API の側で許可を返すのが直し方だと言えるか
  • 許可を広げすぎる危うさ (何でも * にする) に気づけるか

短い答え

  • ブラウザには、JavaScript が別のオリジン (スキーム、ホスト、ポートの組) から受け取った応答を、勝手に読めないようにする決まりがあります。
  • CORS は、サーバーが応答のヘッダーで「このオリジンからなら読んでよい」と許す仕組みで、許可が無いとブラウザが応答を読ませずにエラーにします。
  • 直すのは API の側で、Access-Control-Allow-Origin に画面のオリジンを返すようにします。必要なら、先に届く OPTIONS の確かめにも答えます。

少し詳しい答え

なぜブラウザが止めるのか

ブラウザは、開いているサイトのログインの Cookie などを、ほかのサイトへの要求にも付けて送ることがあります。どのサイトの JavaScript でも、ほかのサイトの応答を自由に読めたら、悪いサイトが利用者の個人の画面を読み取れてしまいます。だから、オリジンが違う応答は、相手のサーバーが許したときだけ読ませます。

たとえば http://localhost:5173 の画面から http://localhost:3000 の API を呼ぶと、ポートが違うので別のオリジンです。

直し方

API の応答の Access-Control-Allow-Origin のヘッダーに、http://localhost:5173 のように画面のオリジンを入れて返します。本番では、本番の画面のオリジンを書きます。多くのサーバーの部品 (Express の cors など) は、この設定を数行で入れられます。

プリフライト

JSON を送る POST や、PUT、DELETE、独自のヘッダーを付けた要求では、ブラウザが本番の要求の前に OPTIONS で「この方法で送ってよいか」を確かめます。これがプリフライトです。サーバーは許すメソッドとヘッダーを答え、それが無いと本番の要求は送られません。

Cookie を付けるとき

fetch で credentials: "include" を付けて Cookie を送るなら、Access-Control-Allow-Origin に * は使えません。オリジンをはっきり書き、Access-Control-Allow-Credentials も返します。

作った物と結ぶなら、たとえば「画面と API を別のポートで動かしたら CORS のエラーが出たので、API の側で画面のオリジンだけを許すように設定した」のように話します。

よくある間違い

  • 画面の側のコードで直そうとする許すかどうかを決めるのはサーバーの応答です。fetch の書き方を変えても、許可が無ければ読めません
  • 「CORS がサーバーへの攻撃を防ぐ」と思う CORS はブラウザの中だけの決まりです。curl などはそのまま呼べるので、API の認証と権限の確かめは別に要ります
  • とりあえず全部 * で許す 公開してよい物なら問題は小さいですが、ログインの要る API で許す先を広げると、意図しないサイトから使われる入り口になります

深掘りの問い

  • 「CORS のエラーのとき、要求はサーバーに届いていますか」 届いていることもあります。プリフライトの要らない要求は送られ、ブラウザは応答を読ませないだけなので、サーバーで処理は走りうる、と答えます
  • 「プリフライトが起きないのはどんな要求ですか」 GET、HEAD、POST で、Content-Type が form や text/plain などに限られ、独自のヘッダーが無いもの、と答えます
  • 「開発のときだけ CORS を避ける方法は」開発用のサーバーの中継 (プロキシ) で、画面と API を同じオリジンに見せる方法を挙げます

確認日 2026年10月23日

技術面接問題の一覧へ戻る