CORSポリシーに関するエラーに多々遭遇していたのですが、なんとなくで解決していたので深く理解することを目標にこの記事を書いています。
CORSとは?
CORS(Cross-Origin Resource Sharing)とは異なるオリジン間のリクエストを制御するためのブラウザ機能になります。オリジンとは、URLのプロトコル、ホスト、ポートの組み合わせで定義されます。
異なるオリジンの例
-
https://example.com
とhttp://example.com
→ プロトコルが異なる -
https://example.com:8080
とhttps://example.com
→ ポートが異なる -
https://example.com
とhttps://api.example.com
→ ホストが異なる
CORSエラーが発生する理由
CORSエラーは、ブラウザが送信したリクエストがサーバー側で許可されていない場合に発生します。エラーが発生した場合は、以下のようなエラーが表示されます。
Access to XMLHttpRequest at 'https://api.example.com/data' from origin 'https://frontend.example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
CORSエラーを実際に引き起こしてみる
CORSエラーを実際に引き起こしてみたいと思います。
まず、サーバー側はNode.jsを使用して構築します。
ステップ1: expressのインストール
expressを使用してサーバーを作成していきます。
まず最初に、プロジェクトを初期化して、package.jsonファイルを作成します。その後、パッケージをインストールします。
npm init -y
npm install express
ステップ2: Nodeアプリケーションの作成
簡単なNodeアプリケーションを作成していきます。今回はポート番号3000を使用します
const express = require("express")
const app = express()
const port = 3000
app.listen(port, ()=>{
console.log(`Server is running on port ${port}`)
})
app.get("/data", (req, res) => {
res.json({ message: "Hello World!" });
});
コードが書けたらNodeサーバーを起動します。
起動すると、Server is running on port 3000
と表示されます。
node server.js
ステップ3: クライアント側の作成
以下のHTMLファイルを用意し、ブラウザで開きます。
<script>
タグ内では、fetch
関数を使用してサーバー(http://localhost:3000/data
)にリクエストを送信します。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">[title](url)
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>CORS</title>
</head>
<body>
<h1>Hello Wolrd</h1>
<script>
fetch("http://localhost:3000/data")
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error("CORS Error:", error));
</script>
</body>
</html>
ステップ4: 検証ツールのconsoleを確認する
ウェブページ上で右クリック → 「検証」をクリックします。そうすると、上部にいろんなタブが出てくるので、Consoleを選択します。Consoleを開くと、赤くCORSエラーが表示されています。
今回は、ポートが異なっているので、CORSエラーが出ていました。
- http://localhost:5500: クライアント側で動作しているオリジン
- http://localhost:3000: サーバー側で動作しているオリジン
CORSエラーを解消する
ここまででCORSエラーを実際に確認することができたので、その解消を行っていきます。
ステップ1: cors
ライブラリのインストール
npm install cors
ステップ2: サーバーコードにCORSを適用
下記のコードでは、どのオリジンからのリクエストも許可するCORSポリシーを設定しています。
const express = require("express")
const app = express()
const cors = require("cors"); // corsをインポート
const port = 3000
// CORSを適用
app.use(cors());
app.listen(port, ()=>{
console.log(`Server is running on port ${port}`)
})
app.get("/data", (req, res) => {
res.json({ message: "Hello World!" });
});
ステップ3: 特定のオリジンを許可する
今回は、http://localhost:5500
からアクセスをしたいので、こちらのオリジンからのみアクセスを許可するように設定をします。
app.use(cors({
origin: "http://localhost:5500"
}));
設定ができたら再度サーバーを起動します。
node server.js
ステップ4: 動作の確認
設定ができたので実際にCORSエラーは解消できているのか確認していきます。
先ほどのHTMLファイルをブラウザで開き、検証ツールで確認すると下記のように表示されているかと思います。
ステップ5: 特定のオプションを追加する場合(おまけ)
リクエストに応じてヘッダーやHTTPメソッドを設定するオプションがもあります。
app.use(cors({
origin: "http://localhost:5500", // 許可するオリジン
methods: ["GET", "POST"], // 許可するHTTPメソッド
allowedHeaders: ["Content-Type", "Authorization"], // 許可するヘッダー
credentials: true // Cookieなどの認証情報を許可
}));
おわりに
websocketサーバーをALBを使用して負荷分散を行ってるいるのですが、CORSエラーがでてなかなか解決できず。。。難しいですね!
最後までご覧いただきありがとうございました!