CORS とモジュール

ES Modules をブラウザで使用する際、異なるオリジン(ドメイン)からモジュールを読み込む場合は CORS(Cross-Origin Resource Sharing)のルールに従う必要があります。

モジュールは常に CORS リクエスト

通常のスクリプトとは異なり、type="module" で読み込むスクリプトは常に CORS リクエストとして扱われます。

通常のスクリプト

<script src="https://外部サイト/script.js"> は CORS なしで読み込める

モジュール

<script type="module" src="https://外部サイト/module.js"> は CORS が必要

同一オリジンの場合

同じドメイン、ポート、プロトコルからの読み込みであれば、特別な設定は不要です。

<!-- 同一オリジン(問題なし) -->
<script type="module" src="/js/main.js"></script>
<script type="module" src="./utils.js"></script>

異なるオリジンの場合

CDN や外部サービスからモジュールを読み込む場合、サーバー側で CORS ヘッダーを設定する必要があります。

<!-- 外部オリジン(CORS 設定が必要) -->
<script type="module" src="https://cdn.example.com/lib.js" crossorigin></script>

サーバーは以下のヘッダーを返す必要があります。

Access-Control-Allow-Origin: *

または特定のオリジンを指定します。

Access-Control-Allow-Origin: https://your-site.com

crossorigin 属性

モジュールの script タグには crossorigin 属性を指定します。

<!-- 匿名モード(資格情報なし) -->
<script type="module" src="https://cdn.example.com/lib.js" crossorigin></script>
<script type="module" src="https://cdn.example.com/lib.js" crossorigin="anonymous"></script>

<!-- 資格情報を含める(Cookie など) -->
<script type="module" src="https://api.example.com/secure.js" crossorigin="use-credentials"></script>
crossorigin 値説明
anonymous(デフォルト)資格情報(Cookie等)を送信しない
use-credentials資格情報を送信する

動的インポートと CORS

import() による動的インポートでも、同様に CORS ルールが適用されます。

// 外部オリジンからの動的インポート
try {
  const module = await import('https://cdn.example.com/lib.js');
} catch (error) {
  console.error('CORS エラーの可能性:', error);
}

ローカル開発での注意

file:// プロトコルでは、CORS の制限により他のファイルをインポートできません。

Access to script at 'file:///path/to/module.js' from origin 'null' 
has been blocked by CORS policy

ローカル開発には、開発サーバーを使用してください。

解決方法

ローカルサーバーを起動して http://localhost 経由でアクセスする。VS Code の Live Server 拡張、Python の http.server、Node.js の serve パッケージなどが使えます。

# Python 3
python -m http.server 8000

# Node.js(serve パッケージ)
npx serve

# VS Code
# Live Server 拡張をインストールして使用

CORS エラーの対処

外部モジュールを使う場合は、CORS ヘッダーを返す CDN を選ぶ
自分のサーバーなら、適切な CORS ヘッダーを設定する
ローカル開発では開発サーバーを使用する

CORS の仕組みを理解しておくことで、モジュールの読み込みに関するトラブルを迅速に解決できます。