Allow-Origin の末尾に / が付いている

オリジンをブラウザのアドレスバーからコピーして、末尾のスラッシュごと設定してしまった例です。見た目は正しくても CORS チェックが一致しない理由を、A と B の比較で確かめます。

入力

A: 変更前の応答ヘッダー

Access-Control-Allow-Origin: https://app.example.com/
Access-Control-Allow-Credentials: true

B: 変更後の応答ヘッダー

Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true

リクエストの資格情報(credentials)

つき(Cookie や認証情報を送る。fetch の credentials: include など)

結果

エラー 1 件・警告 0 件・情報 0 件

指摘(エラー・警告・情報)

  • エラー A: Access-Control-Allow-Origin 「https://app.example.com/」はオリジンの形ではありません。オリジンは https://example.com のように「スキーム://ホスト(:ポート)」だけで、末尾の / やパスは付けません。CORS チェックはリクエストのオリジンと値を照らすため、一致せず失敗します(Fetch Standard 3.3.4・4.10)。
差分のあるヘッダー1 項目(全 6 項目中)
A のエラー・警告エラー 1 件・警告 0 件
B のエラー・警告エラー 0 件・警告 0 件
判定A の規則違反(エラー)が B で解消されます
前提のリクエスト資格情報つき(Cookie などを送る)

ヘッダーごとの差分

ヘッダーごとの差分
ヘッダーA(変更前)B(変更後)差分
Access-Control-Allow-Originhttps://app.example.com/https://app.example.comhttps://app.example.com/ → https://app.example.com
Access-Control-Allow-Credentialstruetrue同じ
Access-Control-Allow-Methods(なし)(なし)(どちらもなし)
Access-Control-Allow-Headers(なし)(なし)(どちらもなし)
Access-Control-Max-Age(なし=既定 5 秒)(なし=既定 5 秒)同じ(有効な値 5 秒)
Access-Control-Expose-Headers(なし)(なし)(どちらもなし)

検算(この結果になる理由)

オリジンは「スキーム://ホスト(:ポート)」だけで、パスや末尾の / は含みません(Fetch 3.3.4)。CORS チェックはリクエストのオリジンと値を照らす(4.10)ため、A は一致せずエラー 1 件です。B は問題なしで、差分は Allow-Origin の 1 項目です。

判定の根拠は仕様と根拠に、仕様の出典とともにまとめています。自分の入力で試すにはツールをお使いください。

このツールの制約

ご利用にあたって

  • 結果は Fetch Standard にもとづく読み解きで、個々のブラウザやプロキシ、CDN での実際の動作を保証するものではありません。
  • 本番の設定を変えるときは、検証環境で実際のブラウザの開発者ツールを使い、リクエストが通ることを確認してください。

ほかの入力例