Contents
CORSエラーとは
CORSは「異なるオリジン(ドメイン、プロトコル、ポート)間でのリソース共有」を制御するセキュリティの仕組みです。
そのため異なるオリジン間でリソースをリクエストしようとする際にブラウザが制限をかけることにより、CORSエラーが発生します。
「Access-Control-Allow-Origin」の設定
異なるオリジン間のリクエストで制限をうけずにアクセスするためには、レスポンスヘッダーに「Access-Control-Allow-Origin」を指定することで可能になります。
プリフライトリクエストとは
異なるオリジン(ドメイン)へリクエストを送る前の「事前確認」
- 本来のリクエストを送る前に、そのリクエストが安全かどうかを確認します
- HTTPの
OPTIONS
メソッドを使用して送信されます
プリフライトリクエストはブラウザが自動的に行います。開発者が明示的にコードを書く必要はありません。
プリフライトが必要になるケース
- 特殊なヘッダーを使用する場合
application/json
などの特殊なContent-Typeを使用する場合- GET/POST/HEAD以外のメソッド(PUT、DELETEなど)を使用する場合
プリフライトリクエストの流れ
ブラウザがOPTIONS
リクエストを送信 サーバーがCORS設定を返答 許可された場合のみ、本来のリクエストを送信
開発者ツールでの確認方法
- ブラウザの開発者ツールを開く
- Networkタブで確認
- OPTIONSメソッドのリクエスト → これがプリフライトリクエスト
- その直後の本来のリクエスト
リクエストヘッダー:
- Origin: [送信元のドメイン]
- Access-Control-Request-Method: [使用予定のメソッド]
- Access-Control-Request-Headers: [使用予定のヘッダー]
レスポンスヘッダー:
- Access-Control-Allow-Origin: [許可されているドメイン]
- Access-Control-Allow-Methods: [許可されているメソッド]
- Access-Control-Allow-Headers: [許可されているヘッダー]
ステータスコード(参考)
HTTPのレスポンスヘッダの先頭に必ず入ってます
ステータスコード | 名前 | 説明 |
---|---|---|
200 | OK | リクエスト成功 |
202 | Accepted | リクエスト成功したが、処理はまだ |
301 | Moved Permanently | リソースは恒久的に移動 |
302 | Found | リクエストしたリソースは一時的に移動 |
307 | Temporary Redirect | リクエストしたリソースは一時的に移動 |
400 | Bad Request | リクエストが正しくない |
403 | Forbidden | アクセスが禁止されている |
404 | Not Found | 指定したリソースが見つからない |
405 | Method Not Allowed | 指定したメソッドを使えません |
406 | Not Acceptable | Accept関連のヘッダに問題 |
413 | Request Entity Too Large | リクエストボディが大きすぎる |
415 | Unsupported Media Type | サポートしていないメディアタイプ |
429 | Too Many Requests | リクエスト回数が多すぎる |
500 | Internal Server Error | サーバー側でエラーが発生 |
503 | Service Unavailable | サーバーが一時的に停止 |

(注意)プリフライトリクエストを扱うPHPスクリプトの設計
クロスオリジン(別ドメインからのfetchなど)を想定したPHPスクリプトでは、必ずOPTIONSリクエストへの対応が必要です。
<?php
// CORSヘッダー設定
header("Access-Control-Allow-Origin: https://example.com");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");
// OPTIONSリクエスト(プリフライト)への対応
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
exit(); // ← 必須!ここで終了
}
// 以下、本処理(POSTなど)
// データベース処理
// メール送信
// など
?>
上記のように記述しないとOPTIONメソッドリクエストと本リクエストで2重でPHPスクリプトの処理がコールされてしまいます。
クロスオリジンを扱うPHPでは、OPTIONSリクエストでexitして、メイン処理の重複実行を防ぐ必要があります