CORSエラーと一般的なAccess-Control-Allow-Origin問題の解決方法:完全ガイド
異なるドメインのAPIに対してリクエストを行うWebアプリケーションを構築したことがあるなら、ほぼ確実に恐ろしい「CORSエラー」に遭遇したことがあるでしょう。通常、ブラウザのコンソールには次のように表示されます。
Access to fetch at 'https://api.example.com' from origin 'https://myapp.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
このガイドでは、CORSとは何か、なぜ存在するのか、そしてこれらのエラーを完全に修正する方法について詳しく説明します。
1. 一般的なCORSエラーメッセージ
主にブラウザの開発者ツール(コンソールまたはネットワークタブ)で以下のエラーが表示されます。
blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present ...The 'Access-Control-Allow-Origin' header contains multiple values ...Response to preflight request doesn't pass access control check ...Method NOT ALLOWED ...(POSTやDELETEなどのHTTPメソッドがCORSによって許可されていない場合)
2. CORSとは何か?
CORS (Cross-Origin Resource Sharing) は、ブラウザによって実装されているセキュリティ機能です。悪意のあるWebサイトが、許可なく別のドメイン(銀行やプライベートAPIなど)に対してリクエストを行うのを防ぎます。
デフォルトでは、ブラウザは**同一生成元ポリシー(Same-Origin Policy)**に従います。つまり、a.com上のスクリプトはa.comからのみデータを要求できます。CORSは、b.comが明示的に許可した場合に限り、a.comがb.comから安全にデータを要求できるようにする仕組みです。
3. 主な原因と解決策
3.1 「Access-Control-Allow-Origin」ヘッダーの欠如
これは最も一般的なエラーです。データを要求しているサーバーが、あなたのドメインがリソースにアクセスすることをブラウザに伝えていないことを意味します。
解決策:
修正は必ずサーバー側で行う必要があります。レスポンスに Access-Control-Allow-Origin ヘッダーを追加する必要があります。
- パブリックAPIの場合:
*(すべて許可)に設定します。 - プライベートAPIの場合: 特定のドメイン(例:
https://myapp.com)に設定します。
3.2 CORS プリフライト (CORS preflight) の失敗
「複雑な」リクエスト(カスタムヘッダーを持つものや、PUT/DELETEなどのメソッドを使用するもの)の場合、ブラウザは最初に自動的な OPTIONS リクエストを送信します。これは プリフライト(Preflight) リクエストと呼ばれます。
エラー内容:
Response to preflight request doesn't pass access control check.
解決策:
サーバーが OPTIONS リクエストを処理し、正しいCORSヘッダーとともに 200 OK または 204 No Content ステータスを返すようにします:
Access-Control-Allow-OriginAccess-Control-Allow-Methods(例:GET, POST, OPTIONS, PUT, DELETE)Access-Control-Allow-Headers(例:Content-Type, Authorization)
3.3 「Access-Control-Allow-Credentials」
リクエストでクッキーや認証ヘッダーを送信する場合(withCredentials: true)、CORSルールはより厳格になります。
エラー内容:
The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
解決策:
Access-Control-Allow-Originにワイルドカード*を使用することはできません。正確なオリジンを指定する必要があります。- ヘッダー
Access-Control-Allow-Credentials: trueも追加する必要があります。
4. さまざまな環境でのCORS修正方法
4.1 Node.js (Express)
最も簡単な方法は、cors ミドルウェアを使用することです:
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors({
origin: 'https://myapp.com',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
credentials: true
}));
4.2 Nginx
サーバーまたはロケーションブロックに以下の行を追加します:
add_header 'Access-Control-Allow-Origin' 'https://myapp.com' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE' always;
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always;
if ($request_method = 'OPTIONS') {
return 204;
}
4.3 Python (Flask)
flask-cors 拡張機能を使用します:
from flask import Flask
from flask_cors import CORS
app = Flask(__name__)
CORS(app, origins=["https://myapp.com"])
5. よくある質問 (FAQ)
Q: フロントエンド(JavaScript)からCORSエラーを修正できますか?
A: いいえ。 CORSは、ブラウザによって強制されるサーバー側のセキュリティポリシーです。JavaScriptコードでそれを「バイパス」することはできません。サーバーを制御できない場合は、代わりにデータを取得してくれる プロキシサーバー(Proxy Server) を使用する必要があります。
Q: なぜCORSエラーはブラウザでしか発生せず、Postmanでは発生しないのですか?
A: PostmanはWebブラウザではなく、スタンドアロンのアプリケーションです。同一生成元ポリシーやCORSルールを強制しません。CORSを強制するのはWebブラウザ(Chrome、Firefoxなど)のみです。
Q: Access-Control-Allow-Origin を "*" に設定するリスクは何ですか?
A: 公開データの場合、リスクはありません。ただし、ユーザーデータを扱ったり認証が必要なAPIの場合、* に設定すると、あらゆるWebサイトがログイン中のユーザーに代わってリクエストを行えるようになり、データ盗難につながる可能性があります。
6. CORSヘッダーのまとめ表
| ヘッダー | 説明 |
|---|---|
Access-Control-Allow-Origin |
リソースへのアクセスを許可するドメインを指定します。 |
Access-Control-Allow-Methods |
許可されるHTTPメソッド(GET、POSTなど)を指定します。 |
Access-Control-Allow-Headers |
送信可能なカスタムヘッダーを指定します。 |
Access-Control-Allow-Credentials |
credentials フラグが true の場合にレスポンスを共有できるかどうかを示します。 |
Access-Control-Max-Age |
プリフライトリクエストの結果をキャッシュできる期間を指定します。 |
関連するエラー
- JSONの 'Unexpected token' エラーの解決方法
- JavaScriptでの 'URIError: URI malformed' の修正方法
- JWTの期限切れおよび一般的なJWTエラーの解決方法