Loading
  • LIGHT

  • DARK

ROUTE

ルートゼロの
アクティビティ

JavaScriptでCORSエラーが出たときの原因と対処法を徹底解説

4

CORSエラーってなに?なぜこの記事が必要なのか

JavaScriptで外部のAPIと連携しようとしたとき、次のようなエラーを見たことがありませんか?

Access to fetch at 'https://api.example.com/data' from origin 'http://localhost:3000' has been blocked by CORS policy

「APIにアクセスしようとしただけなのに、なんでブロックされるの?」
「CORSってよく聞くけど、どうすれば直せるの?」

そんな疑問やモヤモヤに応えるために、この記事では「CORSエラーの意味・原因・確認ポイント・解決方法」まで、実際のコード付きでわかりやすく解説します。


CORSの基本とJavaScriptでのエラー例

CORSをざっくり解説

CORS(Cross-Origin Resource Sharing)とは、「異なる場所にあるWebサービスとのやりとりを、制限付きで許可する仕組み」です。

  • 「異なる場所」=オリジンが異なることを指します。
    ※オリジンとは、「プロトコル(http/https)・ドメイン名・ポート番号」のセットのこと。

たとえば、あなたのWebアプリが「http://localhost:3000」にあり、外部APIが「https://api.example.com」にある場合、これは異なるオリジンです。

Webブラウザは、セキュリティのために「違うオリジンからのデータ取得」を制限します。これがCORSエラーの元です。


具体的なCORSエラー例と原因

以下のようなメッセージが出た場合、それはCORSに関連しています。

No 'Access-Control-Allow-Origin' header is present on the requested resource.

主なCORSエラーの原因

  1. サーバーが許可していない
    APIサーバー側が「どのオリジン(アクセス元)を許可するか」をレスポンスヘッダーで明示していないと、ブラウザが通信をブロックします。

  2. プリフライトリクエストが失敗している
    特定の条件(例:カスタムヘッダー付きのPOST)では、事前確認のためのOPTIONSリクエスト(プリフライト)が送られます。このリクエストに対してサーバーが正しく応答しないと、実際の通信も拒否されます。

  3. 認証情報付きリクエストの制限
    クッキーやトークンを含むリクエストを送信する場合、credentials: ‘include’ などの設定が必要です。さらにサーバー側でも Access-Control-Allow-Credentials: true の設定が必要です。

  4. オリジンが一致していない
    リクエストを送る元のURLと、APIのURLのドメイン・ポート・プロトコルが1つでも異なると、オリジンが異なると判断されます。これがCORSチェックの対象になります。


対処法とコード例

✅方法1:サーバー側で「許可」を明示する

最も確実なのはAPIのサーバー側で「このサイトからのアクセスを許可します」と設定することです。

Node.js(Express)の場合:

const express = require('express');
const app = express();

app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', 'http://localhost:3000'); // 許可したいURL
  res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  next();
});

app.get('/api/data', (req, res) => {
  res.json({ message: 'データ取得成功' });
});

補足

  • Access-Control-Allow-Origin … どのオリジンを許可するか(*も可。ただし制限あり)

  • Access-Control-Allow-Credentials … 認証情報(クッキーなど)付きの場合に必要


開発中は「プロキシ」で回避する

開発中に自分で管理できないAPIを使いたい場合は、「同一オリジンに見せかける」プロキシを使うのも手です。

例:React(Vite)での設定(vite.config.js)

server: {
  proxy: {
    '/api': {
      target: 'https://api.example.com',
      changeOrigin: true,
      rewrite: path => path.replace(/^/api/, '')
    }
  }
}

仕組み:

あなたのReactアプリ(localhost:3000)
      ↓
ローカルで `/api/xxx` にリクエスト
      ↓
Viteが裏で https://api.example.com に転送(CORSを回避)

fetchで認証付き通信を行う場合

fetch('https://api.example.com/data', {
  method: 'GET',
  credentials: 'include' // 認証情報を含める設定
})
  .then(res => res.json())
  .then(data => console.log(data))
  .catch(err => console.error('エラー発生:', err));

注意点

  • サーバー側でも Access-Control-Allow-Credentials: true が必要になります。

  • この場合、Access-Control-Allow-Origin を * にできません。オリジンを明示する必要があります。


まとめ

  • CORSは、異なるサイト間のデータ取得を制限する仕組み。

  • JavaScriptでAPI連携する場合、CORSの制約で通信がブロックされることがある

  • サーバー側の設定 or 開発中はプロキシで対応するのが基本。

  • 認証情報付きの通信には、追加設定が必要。

【外部リンク】

MDN Web Docs: CORS(クロスオリジンリソースシェアリング)

MDN Web Docs: Fetch API

MDN Web Docs: Access-Control-Allow-Origin

Express公式: CORSミドルウェア

Vite公式: server.proxy 設定

【内部リンク】

JavaScriptのAjax完全入門|fetchの使い方・CORSエラーの対処・非同期通信の基本を解説

JavaScriptでよく発生するエラー「ReferenceError」「SyntaxError」などの原因と対策を具体例付きで解説

【初心者でも簡単!】JavaScriptで始める簡単プログラミング|音声文字起こしツール作成ガイド

RANKINGranking-icon

LATEST POSTS

もっとルートゼロを知りたいなら

DISCOVER MORE