エラーの内容
Reactアプリケーションとはポートやドメインが異なる外部APIやバックエンドからデータを取得しようとすると、ブラウザのコンソールに次のようなエラーが表示されます:
Access to fetch at 'http://api.example.com' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
このエラーにより、サーバー側でロジックが正常に処理されていても、アプリケーションはデータを受け取れず、ネットワークリクエストが失敗します。
原因
CORS(Cross-Origin Resource Sharing)は、悪意のあるWebサイトが自身のドメイン以外に対してリクエストを送信するのを防ぐために、ブラウザが実装しているセキュリティ機構です。現代のWeb開発では、ReactアプリはたいていI http://localhost:3000 で動作し、APIは http://localhost:5000 や http://api.example.com で動作します。ドメインまたはポートが異なるため、サーバーが明示的に許可しない限り、ブラウザはレスポンスをブロックします。
解決手順
解決策1:サーバー側で修正する(推奨)
CORSを解決する最も確実な方法は、バックエンドサーバーにReactアプリのオリジンからのリクエストを許可する設定を行うことです。サーバーのレスポンスに Access-Control-Allow-Origin ヘッダーを追加する必要があります。
Node.js / Express の例
cors パッケージをインストールします:
npm install cors
次に、server.js でミドルウェアとして適用します:
const express = require('express');
const cors = require('cors');
const app = express();
// Reactの開発サーバーからのリクエストを許可する
app.use(cors({
origin: 'http://localhost:3000'
}));
app.get('/api/data', (req, res) => {
res.json({ message: 'Success' });
});
app.listen(5000);
Python / FastAPI の例
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
解決策2:開発用プロキシを使う(React側)
バックエンドのコードにアクセスできない場合や、ローカル開発で素早く対処したい場合は、プロキシを使う方法があります。ReactのdevサーバーがAPIサーバーへリクエストを転送することで、ブラウザは同一オリジンからのリクエストとみなします。
Create React App(CRA)の場合
package.json を開き、末尾に proxy フィールドを追加します:
{
"name": "my-react-app",
"version": "0.1.0",
"dependencies": { ... },
"proxy": "http://localhost:5000"
}
追加後、fetchの呼び出しを絶対URLから相対パスに変更します:
// 変更前:
fetch('http://localhost:5000/api/users')
// 変更後:
fetch('/api/users')
注意: この変更を反映するには、Reactの開発サーバーを再起動する必要があります。
Viteプロジェクトの場合
vite.config.ts または vite.config.js で、サーバープロキシを設定します:
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://localhost:5000',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
},
},
},
});
解決策3:手動でプロキシミドルウェアをセットアップする
複数のバックエンドへのプロキシなど、より細かい制御が必要な場合は http-proxy-middleware を使用します。
- パッケージをインストールします:
npm install http-proxy-middleware src/setupProxy.jsというファイルを作成します(どこかにインポートする必要はありません。CRAが自動的に検出します)。
const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
})
);
};
確認手順
- ChromeまたはFirefoxでReactアプリケーションを開きます。
F12キーを押して開発者ツールを開き、Network(ネットワーク) タブに移動します。- APIコールを発火させます(例:ページをリロードするかボタンをクリック)。
- 失敗したリクエストをクリックします。
- Response Headers(レスポンスヘッダー) を確認します。修正が成功していれば、
Access-Control-Allow-Origin: http://localhost:3000(または*)が表示されます。 - Console(コンソール) を確認し、赤いCORSエラーが消えていることを確認します。
補足Tips
- 本番環境で
*は避けること:app.use(cors({ origin: '*' }))はテストには便利ですが、セキュリティ上のリスクがあります。本番環境では必ず特定のドメインを指定してください。 - プロトコルを確認すること:
http://localhost:3000とhttps://localhost:3000は異なるオリジンとして扱われます。両方が一致していることを確認してください。 - プリフライトリクエスト: カスタムヘッダーや
PUT/DELETEメソッドを含む複雑なリクエストでは、ブラウザはまずOPTIONSリクエストを送信します。サーバーがOPTIONSリクエストを処理し、正しいCORSヘッダーを返すことを確認してください。 - CookieとCredentials: CookieやAuthorizationヘッダーを送信する必要がある場合は、fetchのオプションに
credentials: 'include'を設定し、サーバー側ではallow_credentials=Trueを指定してください。

