ReactアプリでCORSポリシーによるブロックエラーを修正する方法

intermediate⚛️ React2026-04-15| React (Create React App, Vite, Next.js), Node.js/Express, Python/FastAPI, Go, PHP

Error Message

Access to fetch at 'http://api.example.com' from origin 'http://localhost:3000' has been blocked by CORS policy
#react#cors#api#fetch#proxy

エラーの内容

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:5000http://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:3000https://localhost:3000 は異なるオリジンとして扱われます。両方が一致していることを確認してください。
  • プリフライトリクエスト: カスタムヘッダーや PUT/DELETE メソッドを含む複雑なリクエストでは、ブラウザはまず OPTIONS リクエストを送信します。サーバーが OPTIONS リクエストを処理し、正しいCORSヘッダーを返すことを確認してください。
  • CookieとCredentials: CookieやAuthorizationヘッダーを送信する必要がある場合は、fetchのオプションに credentials: 'include' を設定し、サーバー側では allow_credentials=True を指定してください。

Related Error Notes