CORSとは、ブラウザで動くJavaScriptが、別オリジンのAPIレスポンスを読めるかどうかを、サーバーのHTTPヘッダーで判断する仕組みです。
たとえば、https://app.example.com の画面から https://api.example.com のAPIを fetch() で呼び出すと、ブラウザは「この別の場所から返ってきたレスポンスをJavaScriptへ渡してよいか」を確認します。

CORSエラーは、通信が一切サーバーへ届いていないという意味ではありません。多くの場合、ブラウザがレスポンスをJavaScriptへ渡さない状態です。
この記事では、CORSの意味、オリジンの考え方、Access-Control-Allow-Origin の役割、プリフライト、よくある直し方を初心者向けに整理します。
まず結論:CORSは別オリジンAPIの受付ゲート
CORSは、Cross-Origin Resource Sharingの略です。日本語では「オリジン間リソース共有」と説明されますが、最初は 別のオリジンにあるAPIのレスポンスを、ブラウザ上のJavaScriptが読めるようにするための許可ルール と考えると分かりやすいです。
重要なのは、CORSの判断をしている中心がブラウザだという点です。サーバーはレスポンスに許可ヘッダーを付け、ブラウザはそのヘッダーを見て、JavaScriptへレスポンスを渡すかどうかを決めます。
次の図では、画面のJavaScript、ブラウザ、APIサーバーの間にある「受付ゲート」としてCORSを見てください。どこで許可を確認しているかを押さえると、エラーの読み方が変わります。

CORSエラーが出る典型例
CORSエラーは、フロントエンドとAPIを別々の場所で動かすとよく出ます。学習中なら、ReactやVueなどの開発サーバーが http://localhost:3000、APIサーバーが http://localhost:8080 という構成で起きやすいです。
fetch("http://localhost:8080/api/users")
.then((response) => response.json())
.then((users) => console.log(users));
このコード自体が間違っているとは限りません。問題は、ブラウザから見ると localhost:3000 と localhost:8080 はポートが違うため、別オリジンとして扱われることです。
そのためAPIサーバー側が、http://localhost:3000 からの読み取りを許可するヘッダーを返さないと、ブラウザはJavaScriptにレスポンスを渡しません。
オリジンとは何か
オリジンとは、Web上の出どころを表す単位です。MDNの同一オリジンポリシーの説明でも、オリジンはスキーム、ホスト、ポートの組み合わせとして扱われます。
スキームは https や http、ホストは example.com のような名前、ポートは 443 や 3000 のような番号です。どれか1つでも違うと、ブラウザは別オリジンとして扱います。
次の図では、オリジンを3点セットとして見てください。CORSエラーの原因を探すときは、ドメインだけでなく、http と https の違いやポート番号の違いも確認します。

| 比較 | 例 | 判定 |
|---|---|---|
| 同じ | https://example.com/app と https://example.com/api | スキーム、ホスト、ポートが同じなので同一オリジン |
| スキーム違い | http://example.com と https://example.com | httpとhttpsが違うので別オリジン |
| ホスト違い | https://app.example.com と https://api.example.com | ホスト名が違うので別オリジン |
| ポート違い | http://localhost:3000 と http://localhost:8080 | ポートが違うので別オリジン |
同一オリジンポリシーとCORSの関係
ブラウザには、同一オリジンポリシーという重要なセキュリティの仕組みがあります。これは、あるオリジンで読み込まれた文書やスクリプトが、別オリジンのリソースへ自由にアクセスしないように制限する考え方です。
もしこの制限がなければ、悪意のあるページが、利用者がログイン中の別サイトの情報をブラウザ経由で読み取れてしまう可能性があります。CORSは、この制限を壊す仕組みではなく、サーバーが明示的に許可した範囲だけ例外を作る仕組みです。
つまり、同一オリジンポリシーは基本のブレーキ、CORSはサーバーが許可した相手だけに開くゲートです。
CORSの流れ
CORSでは、ブラウザがリクエストに Origin ヘッダーを付けることがあります。APIサーバーは、そのOriginを見て、許可する場合はレスポンスに Access-Control-Allow-Origin を返します。
次の図では、Origin、許可ヘッダー、ブラウザの照合、JavaScriptへの受け渡しの順番を見てください。CORSの主役が「ブラウザの照合」であることが分かります。

Origin: https://app.example.com
Access-Control-Allow-Origin: https://app.example.com
上のように、リクエスト元のOriginと、レスポンスの Access-Control-Allow-Origin が対応していれば、ブラウザはレスポンスをJavaScriptへ渡せます。対応していなければ、コンソールにCORSエラーが表示されます。
Access-Control-Allow-Originの意味
Access-Control-Allow-Origin は、APIサーバーが「このオリジンのJavaScriptには、レスポンスを読ませてよい」とブラウザへ伝えるレスポンスヘッダーです。
開発中にすべてを許可したくなり、* を設定する例を見ることがあります。公開APIのように誰が読んでもよいリソースでは選択肢になりますが、ログイン情報やCookieを含むリクエストでは注意が必要です。
Access-Control-Allow-Origin: https://app.example.com
Vary: Origin
特定の画面からだけAPIを読ませたい場合は、上のように具体的なオリジンを返します。複数のオリジンを許可する場合でも、レスポンスには実際のリクエスト元に対応した1つのオリジンを返す実装が一般的です。
また、Cookieなどの認証情報を含める場合は、Access-Control-Allow-Credentials: true やJavaScript側の credentials: "include" も関係します。この場合、Access-Control-Allow-Origin: * を安易に使えない点に注意します。
プリフライトとは何か
プリフライトとは、本番のリクエストを送る前に、ブラウザが OPTIONS メソッドで事前確認する仕組みです。すべてのCORSリクエストで必ず発生するわけではありません。
たとえば、PUT や DELETE、独自ヘッダー、JSONの Content-Type: application/json などが関係すると、ブラウザは先に「このメソッドやヘッダーで送ってよいか」をAPIサーバーへ確認することがあります。
次の図では、プリフライトを「受付での事前確認」として見てください。OPTIONSが失敗すると、本番のPOSTやPUTの前に止まって見えることがあります。

OPTIONS /api/users HTTP/1.1
Origin: https://app.example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: content-type
APIサーバーは、この事前確認に対して、許可するメソッドやヘッダーを返します。ここで必要なヘッダーが不足していると、ブラウザは本番リクエストへ進めません。
CORSエラーの直し方
CORSエラーが出たときは、まずブラウザのConsoleだけで判断せず、Networkタブで実際のリクエストとレスポンスヘッダーを見ます。特に、Origin、Access-Control-Allow-Origin、プリフライトの OPTIONS を確認します。
次の図では、CORSエラーを調べる順番を見てください。フロントエンドの fetch() を何度も書き換える前に、APIサーバーがどのヘッダーを返しているかを確認するのが近道です。

根本的な修正は、多くの場合APIサーバー側で行います。フロントエンド側でCORSヘッダーを追加しても、ブラウザが見ているのはAPIサーバーから返ってくるレスポンスヘッダーです。
CORSと認証・CSRF対策の違い
CORSはセキュリティに関係しますが、認証や権限チェックそのものではありません。CORSを許可したからといって、ログイン不要で何でも見せてよいという意味にはなりません。
認証は、利用者が誰かを確認する仕組みです。権限チェックは、その利用者がそのデータを見たり操作したりしてよいかを判断する仕組みです。CSRF対策は、利用者のブラウザを勝手に使った操作を防ぐための仕組みです。
次の図では、CORS、認証、CSRF対策の役割を分けて見てください。CORSは「読む許可」の話であり、本人確認や権限確認の代わりではありません。

既存記事とあわせて読む順番
CORSは、JavaScriptの fetch()、HTTPヘッダー、Web APIの理解とつながっています。先にAPIやHTTPの用語を押さえておくと、CORSエラーの原因を読みやすくなります。
- 【JavaScript】fetch APIとは?GETとPOSTの使い方
- APIとは?APIとWeb APIの違い
- REST APIとは何か?
- HTTPとは?HTTPSとは?
- async/awaitとは?Promiseとの違い
公式情報と確認先
仕様として確認する場合は、WHATWG Fetch StandardとMDNのCORS、同一オリジンポリシーの説明を参照します。Fetch Standardは、fetch、CORSプロトコル、リダイレクトなど、ブラウザの取得処理を一貫した仕組みとして定義しています。
まとめ
CORSは、別オリジンのAPIレスポンスをブラウザ上のJavaScriptが読めるかどうかを、サーバーのHTTPヘッダーで判断する仕組みです。
CORSエラーが出たら、まずConsole、Network、レスポンスヘッダー、サーバー設定の順に見ます。フロントエンドだけで解決しようとせず、APIサーバーが正しい許可ヘッダーを返しているかを確認しましょう。
