CORSはなぜ怒るのか — ブラウザ先生の検問所
フロントエンド開発をしていると、ほぼ全員が一度はこの赤いエラーに出会います — 「blocked by CORS policy」。コードは正しいはずなのに、ブラウザが通信を握りつぶす。なぜでしょうか。
たとえるなら、自分の学校(サイトA)の校庭から、別の学校(サイトB)の敷地のおもちゃに手を伸ばした瞬間、ブラウザ先生に「待ちなさい!」と止められている状態です。下の図1で、検問のいきさつと通れるようになるまでを順に追ってみましょう。
site-a.example ✓
ブロックしているのはサーバーではなく、ブラウザ
図1のステップ4で見たのがいちばん大事なポイントです。CORSエラーのとき、リクエストはサーバーに届いていて、返事も返ってきています。その返事に「site-a の生徒に渡していいよ」という許可証(Access-Control-Allow-Originヘッダ)が付いていないから、ブラウザがあなたのJavaScriptに渡す直前で握りつぶしているのです。
この検問の土台が同一オリジンポリシーです。もしこの仕組みがなければ、悪意あるサイトを開いただけで、そのページのJavaScriptがあなたのログイン済みの銀行サイトのAPIを勝手に呼び、結果を読み取れてしまいます。CORSは「不便な制限」ではなく、サーバーが明示的に許可した相手にだけ例外的に門を開ける、安全のための仕組みなのです。
だからCORSエラーは、フロントエンドのコードをいくらいじっても根本的には直りません。許可証を出せるのはサーバー側だけ。「サーバーの設定で許可するオリジンを足す」が正攻法です。
- オリジン
- スキーム+ドメイン+ポートの組。1つでも違えば「別の学校」扱いになる。
- プリフライト
- 本番の前にOPTIONSで「触っていい?」と偵察するリクエスト。ブラウザが自動で送る。
- Access-Control-Allow-Origin
- サーバーが返す許可証ヘッダ。「このオリジンの生徒なら渡してよし」の宣言。
まとめ
CORSの登場人物は3人 — お願いするJavaScript、許可証を出すサーバー、そして検問するブラウザ。エラーの正体は「サーバーが許可証を出していないので、ブラウザが返事を渡さなかった」です。次にあの赤いエラーを見たら、ネットワークタブを開いてみてください。返事はちゃんと届いていて、足りないのはヘッダ1行だけ、というのが自分の目で確かめられます。