概要: このチュートリアルでは、CORS (Cross-Origin Resource Sharing) について、また、あるオリジンがデータを取得できるようにWebサーバーを設定する方法について説明します。
オリジンとは
オリジンとは、次の3つの要素のユニークな組み合わせを指します。
- プロトコル (スキーム): URLで指定されたプロトコル(
HTTP
、HTTPS
、FTPS
など) - ドメイン (ホスト): ドメイン名またはIPアドレス(
javascripttutorial.net
や127.0.0.1
など) - ポート: Webサーバーとの通信に使用されるポート番号。ポートを指定しない場合、プロトコルのデフォルトポートが使用されます。例:
HTTPS
の場合はポート443
、HTTP
の場合はポート80
。
例えば、https://javascripttutorial.dokyumento.jp/api/
は、以下のオリジンです。
HTTPS
がプロトコル。www.javascriptttorial.net
がドメイン名。443
がHTTPS
プロトコルのデフォルトポート。
https://api.javascripttutorial.net/
は、ドメイン名 api.javascripttutorial.net
が www.javascripttutorial.net
と異なるため、別のオリジンです。
オリジンは、WebブラウザがCORSとして知られるセキュリティポリシーを適用するために重要です。
CORSとは
CORS (Cross-Origin Resource Sharing) は、Webブラウザのセキュリティ機能で、あるオリジンから別のオリジンへの不正なリクエストを防ぎます。
ブラウザは、サイトが自身のオリジンに対してHTTPリクエストを行うことを許可します。しかし、そのサイトが異なるオリジン (クロスオリジン) をリクエストしようとすると、クロスサイトスクリプティング (XSS) 攻撃のようなセキュリティリスクから保護するために、ブラウザはデフォルトでこのアクションをブロックします。
CORSがどのように機能するかをよりよく理解するために、例を見てみましょう。
簡単なWebサーバーの設定
Node.jsで簡単なExpress Webサーバーを設定します。
ステップ1. プロジェクトファイルを保存するための新しいディレクトリを作成します
mkdir webserver
cd webserver
Code language: JavaScript (javascript)
ステップ2. ターミナルで npm init
コマンドを実行してプロジェクトを初期化します
npm init --yes
Code language: JavaScript (javascript)
このコマンドは、プロジェクトディレクトリにpackage.jsonファイルを作成します。
ステップ3. express
パッケージをインストールします
npm install express
Code language: JavaScript (javascript)
ステップ4. type : "module"
を追加して package.json
を設定します
"type": "module"
Code language: JavaScript (javascript)
これにより、Node.js プロジェクトでES6 モジュールを使用できるようになります。
また、script
セクションも変更します
"scripts": {
"start": "node index.js"
}
Code language: JavaScript (javascript)
scripts
セクションを変更することで、ターミナルで npm start
コマンドを実行して index.js
ファイルを実行できるようになります。
ステップ5. 次のコードで index.js
という名前の新しいファイルを作成します
import express from 'express';
const app = express();
app.get('/', (req, res) => {
res.send('Hello, World!');
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Code language: JavaScript (javascript)
index.js
ファイルでは、http://localhost:3000/
というルートへの GET
リクエストを受け付け、'Hello, World!'
というメッセージを返す Express Web サーバーを作成します。
ステップ6. ターミナルで次のコマンドを実行してWebサーバーを起動します
npm start
ステップ7. Webブラウザで http://localhost:3000/
を開くと、JSONレスポンスが表示されます
{
"message": "Hello, World!"
}
Code language: JavaScript (javascript)
JavaScriptアプリの作成
fetch() メソッドを使用して、APIエンドポイント http://localhost:3000/
を呼び出す簡単なJavaScriptアプリを作成します。
ステップ1. JavaScriptアプリファイルを保存するための新しいディレクトリを作成します
mkdir app
cd app
ステップ2. index.html
ファイルを作成します
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Fetch API - CORS</title>
</head>
<body>
<button id="btn">Fetch</button>
<p id="message"></p>
<script src="app.js"></script>
</body>
</html>
Code language: HTML, XML (xml)
index.html
ファイルには、同じディレクトリ内の app.js
が含まれています。
ステップ3. プロジェクトディレクトリに app.js
ファイルを作成します
const btn = document.getElementById('btn');
const messageElem = document.getElementById('message');
btn.addEventListener('click', async () => {
// reset the message
messageElem.innerHTML = '';
try {
// call the API
const response = await fetch('http://localhost:3000/');
const data = await response.json();
// update the message
messageElem.innerHTML = data.message;
} catch (err) {
messageElem.innerHTML = err.message;
}
});
Code language: JavaScript (javascript)
ステップ4. index.html
を開き (VS codeでライブサーバー拡張機能を使用)、Fetchボタンをクリックすると、メッセージが表示されます。
Failed to fetch
Code language: JavaScript (javascript)
コンソールウィンドウを開くと、次のエラーメッセージが表示されます
Access to fetch at 'http://localhost:3000/' from origin 'http://127.0.0.1:5501' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
Code language: JavaScript (javascript)
理由は、オリジン http://127.0.0.1:5501
からオリジン http://localhost:3000/
のサーバーにHTTPリクエストを行っており、ブラウザがそれをブロックするためです。
WebサーバーでCORSを有効にする
ステップ1. ターミナルを開き、Node.js プロジェクトに cors
パッケージをインストールします
npm install cors
Code language: JavaScript (javascript)
ステップ2. すべてのオリジンからのCORSを有効にするように index.js
ファイルを変更します
import express from 'express';
import cors from 'cors';
const app = express();
app.use(cors());
app.get('/', (req, res) => {
res.send({ message: 'Hello, World!' });
});
app.listen(3000, () => {
console.log('Server is running on port 3000');
});
Code language: JavaScript (javascript)
仕組み。
まず、cors
パッケージから cors
関数をインポートします。
import cors from 'cors';
Code language: JavaScript (javascript)
次に、cors()
関数を呼び出し、その戻り値を app.use
() メソッドに渡します
app.use(cors());
Code language: JavaScript (javascript)
このコード行は、Express Webサーバーに、すべてのオリジンからAPIエンドポイントを呼び出すことを許可するHTTP応答のヘッダーに次のエントリを追加するように指示します。
Access-Control-Allow-Origin: *
Code language: JavaScript (javascript)
アスタリスク (*
) は、任意のオリジンを意味します。
ステップ3. Webサーバーを停止 (Ctrl-Cを押す) してから再び起動して、再起動します
npm start
ステップ4. JavaScriptアプリでFetchボタンをクリックします。Webブラウザに Hello, World!
メッセージが表示されます。
Hello, World!
Code language: JavaScript (javascript)
HTTP応答のヘッダーを調べると、次のエントリが表示されます。
Access-Control-Allow-Origin: *
Code language: JavaScript (javascript)
cors()
関数に http://127.0.0.1:5501
などの特定のオリジンを追加することで、Webサーバーを特定のオリジンからのCORSを許可するように設定できることに注意してください。
// ...
app.use(
cors({
origin: 'http://127.0.0.1:5501',
})
);
// ...
Code language: JavaScript (javascript)
ブラウザによって送信されるオリジンに末尾のスラッシュ (/
) が含まれない場合があるため、オリジンに末尾のスラッシュ (/
) は含まれないことに注意してください。
この場合、Webサーバーは、HTTP応答のヘッダーに次のエントリを追加します
Access-Control-Allow-Origin: http://127.0.0.1:5501/
Code language: JavaScript (javascript)
プロジェクトのソースコードをダウンロード
ここをクリックしてプロジェクトのソースコードをダウンロードしてください
zipファイルを解凍すると、次の2つのディレクトリが表示されます
- webserver
- app
Webサーバーを起動するには、次の手順を実行する必要があります
まず、webserver
ディレクトリに移動します
cd webserver
次に、npm install
コマンドを実行して依存関係をインストールします
npm install
3番目に、Webサーバーを起動します
npm start
概要
- オリジンは、ドメイン、プロトコル、およびポートの3つの要素の組み合わせによって定義されます。
- CORS (Cross-Origin Resource Sharing) は、Webブラウザに組み込まれたセキュリティ機能で、デフォルトでは、あるオリジンが異なるオリジンへのリクエストを行うことを防ぎます。
- すべてのオリジンからのリクエストを許可するには、HTTP応答にヘッダー
Access-Control-Allow-Origin: *
を含めるようにWebサーバーを設定します。