以前、クライアントサイドからリソースを利用するためにどうしたら良いか程度は、少し調べはしていたのですが、 今回は、サーバーサイドも含めて W3C の "Cross-Origin Resource Sharing" に記載されている内容を改めて読み直し & まとめておこうと思いました。 …が、結局、ほとんど仕様の日本語化になってしまいました。。 面倒で端折っている部分もありますが、ほぼ訳されています。
※ここに記載される内容は 2014年1月16日 の Cross-Origin Resource Sharing (Recommendation) 仕様になります。
目次
-
- Access-Control-Allow-Origin レスポンスヘッダー
- Access-Control-Allow-Credentials レスポンスヘッダー
- Access-Control-Expose-Headers レスポンスヘッダー
- Access-Control-Max-Age レスポンスヘッダー
- Access-Control-Allow-Methods レスポンスヘッダー
- Access-Control-Allow-Headers レスポンスヘッダー
- Origin リクエストヘッダー
- Access-Control-Request-Method リクエストヘッダー
- Access-Control-Request-Headers リクエストヘッダー
用語
単純なメソッド
- GET
- HEAD
- POST
単純なヘッダー
- Accept
- Accept-Language
- Content-Language
- Content-Type
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
※ Content-Type ヘッダー は、キーバリューの組み合わせで上記のものを満たす場合、単純なヘッダーとなります。
単純なレスポンスヘッダー
- Cache-Control
- Content-Language
- Content-Type
- Expires
- Last-Modified
- Pragma
リクエスト / レスポンス ヘッダー
レスポンスヘッダー
Access-Control-Allow-Origin レスポンスヘッダー
アクセスが許可されているオリジンがどこかに関する情報を返します。 "*"、"null"、"URLリスト"のいずれかで返します。 Origin リクエストヘッダー に対応します。
1 | Access-Control-Allow-Origin: * |
Access-Control-Allow-Credentials レスポンスヘッダー
プリフライトリクエストに対するレスポンスの1つ。
CORSを行う際、Cookie も共有する場合、true を返します。Cookie を共有しない場合は false を返します。
true を返す際は、 Access-Control-Allow-Origin に "*" が指定できません。
必ず Access-Control-Allow-Origin に CORS を行う オリジン を指定します。
指定する オリジン は リクエスト で受け取る Originヘッダー
の値をそのまま使います。
大文字小文字を区別する "true" または "false" のいずれかを返します。
1 2 | Access-Control-Allow-Origin: http://sample.co.jp/ Access-Control-Allow-Credentials: true |
Access-Control-Expose-Headers レスポンスヘッダー
利用可能なレスポンスヘッダーのホワイトリストを返します。 サーバーからクライアントへレスポンスを返す際、クライアント側で利用可能なカスタムヘッダーのリストになります。
1 2 | Access-Control-Expose-Headers: X-Custom-Response-Header X-Custom-Response-Header: foobar |
Access-Control-Max-Age レスポンスヘッダー
プリフライトリクエストに対するレスポンスの1つ。 プリフライトリクエストをキャッシュする時間を秒で指定します。
1 | Access-Control-Max-Age: 86400 |
Access-Control-Allow-Methods レスポンスヘッダー
プリフライトリクエストに対するレスポンスの1つ。 クライアントからサーバーへリクエストする際、サーバー側で受付可能なメソッドのリストを返します。 クライアントから来る Access-Control-Request-Method リクエストヘッダー に対応します。
1 | Access-Control-Allow-Methods: POST, GET, OPTIONS |
Access-Control-Allow-Headers レスポンスヘッダー
プリフライトリクエストに対するレスポンスの1つ。 クライアントからサーバーへリクエストする際、サーバー側で受付可能なヘッダーのリストを返します。 クライアントから来る Access-Control-Request-Headers リクエストヘッダー に対応します。
1 | Access-Control-Allow-Headers: X-Custom-Request-Header |
リクエストヘッダー
主にブラウザが実装するもの。 新しいブラウザなら対応しているはず どれくらい新しいブラウザが対応しているかは…不明。
Origin リクエストヘッダー
プリフライトリクエストとしてサーバーにリクエストされるヘッダーです。 異なるサーバーへ Ajax アクセス する場合、ブラウザが自動的にプリフライトリクエストとして送信します。
1 | Origin: http://sample.co.jp/ |
Access-Control-Request-Method リクエストヘッダー
プリフライトリクエストとしてサーバーにリクエストされるヘッダーです。 サーバー側に利用したいメソッドを通知します。 サーバー側からは Access-Control-Allow-Methods レスポンスヘッダー に許可されたメソッドのリストが記載されて返ってきます。
1 | Access-Control-Request-Method: POST |
Access-Control-Request-Headers リクエストヘッダー
プリフライトリクエストとしてサーバーにリクエストされるヘッダーです。 サーバー側に利用したいヘッダーを通知します。 サーバー側からは Access-Control-Allow-Headers レスポンスヘッダー に許可されたヘッダーのリストが記載されて返ってきます。
1 | Access-Control-Request-Headers: X-Custom-Request-Header |
リソースサーバー 処理
リソース提供側のプロセスモデルについて記載します。 ここで記載されるプロセスは、リソースを提供するサーバーサイドの処理フローになります。
サーバーサイドで使われる設定に以下のものがあります。
リソース サーバー 設定
- list of origins
- リソースサーバーにアクセス可能(リソース共有可能)な Origin のリスト
- list of methods
- リソースサーバーがサポートするメソッドリスト
- list of headers
- リソースサーバーがサポートするヘッダーリスト
- list of exposed headers
- リソースサーバーがクライアントサイドに利用を許可するヘッダーリスト
- supports credentials
- 認証情報をサポートするかどうか
シンプル リクエスト
- Originヘッダー がなければ終了
- Originヘッダー の値がリソース共有するドメインのリストと一致しなかった場合、何もせず終了 ※ドメイン名は大文字小文字を区別する
- 認証情報サポート [supports credentials] が true の場合
認証情報サポート [supports credentials] が false の場合12
Access-Control-Allow-Origine: [Orignヘッダーに記載の値]
Access-Control-Allow-Credentials: true
1Access-Control-Allow-Origin: ["*" または Originヘッダーに記載の値]
- Exposed Header List を Access-Control-Expose-Headers で出力
プリフライト リクエスト
- Originヘッダー がなければ終了
- Originヘッダー の値がリソース共有するドメインのリスト[list of origins] と一致しなかった場合、何もせず終了 ※ドメイン名は大文字小文字を区別しない
- Access-Control-Request-Method ヘッダー をパース。 Access-Control-Request-Method ヘッダー が存在しない、値のパースに失敗、値が存在しない場合、何もせず終了
- リクエストメソッドが、サポートするメソッドリスト [list of methods] のいずれとも一致しない場合、何もせず終了 ※メソッド名は大文字小文字を区別しない
- Access-Control-Request-Method ヘッダー の値が、サポートするメソッドリスト[list of methods] のいずれとも一致しない場合、何もせず終了 ※メソッド名は大文字小文字を区別しない
- 認証情報サポート [supports credentials] が true の場合、
Access-Control-Allow-Origin ヘッダー および Access-Control-Allow-Credentials ヘッダー を レスポンスヘッダー に追加
認証情報サポート [supports credentials] が false の場合、 Access-Control-Allow-Origin ヘッダー を レスポンスヘッダー に追加12
Access-Control-Allow-Origine: [Orignヘッダーに記載の値]
Access-Control-Allow-Credentials: true
1Access-Control-Allow-Origin: ["*" または Originヘッダーに記載の値]
- 任意で、レスポンスに Access-Control-Max-Age ヘッダー を追加
1
Access-Control-Max-Age: [キャッシュする時間(秒)]
- リクエストメソッド が 単純なメソッド でない場合、
サポートするメソッドリスト [list of methods] の一部を含む Access-Control-Allow-Methods ヘッダー を レスポンスヘッダー に追加
※ サポートするメソッドリスト [list of methods] に設定がない場合、Access-Control-Request-Method の値を、許可できる場合は、そのまま使ってもよい
1
Access-Control-Allow-Methods: [許可するメソッドリスト]
- Access-Control-Request-Method ヘッダー の値が、単純なヘッダーでない または Content-Type である場合、
Access-Control-Allow-Headers ヘッダー を 1つ以上 レスポンスヘッダー に追加
1
Access-Control-Allow-Headers: [許可するヘッダーリスト]
クライアント 処理
ここで記載されるプロセスは、クライアント側(ブラウザ)の処理フローになります。 ブラウザ処理なので、通常の Webアプリ開発 においては、まず実装することがないと思います。
クライアントサイド(ブラウザ)で使われる設定に以下のものがあります。
クライアント 設定
- request URL
- リソースへのリクエストURL。
- request method
- リクエストメソッド。明示的に設定されなければ、GETを設定。
- reques headers
- リクエストヘッダー。明示的に設定されなければ、空を設定。
- request body
- リクエスト本文。
- source orgin
- リクエストの生成元ドメイン名
- referrer source
- Refererヘッダーに定義される document または URL。
- redirect flag
- 自動的にリダイレクトするかどうか。
- omit credentials flag
- 認証情報を無視するかどうか。
- preflight flag
- プリフライトリクエストが必要かどうか。
シンプル リクエスト
- ソースサーバードメイン名 を Origin ヘッダー に追加して、リソースサーバー へ リクエスト
プリフライト リクエスト
- 以下の条件を満たす場合、次のステップへ
- リクエストメソッド が プリフライト 結果 キャッシュ の method に一致する
- リクエストヘッダー が プリフライト 結果 キャッシュ の header に一致する
- リソースサーバーに 以下の条件 で リクエスト(プリフライトリクエスト)
- POSTS メソッド
- Access-Control-Request-Method ヘッダー を追加
- リソースサーバー との間で カスタムヘッダー を利用する場合、Access-Control-Request-Headers ヘッダー を追加
- カスタムヘッダー は 削除
- Cookie は 送信しない
- リクエストボディ は 空
- レスポンスからリソース共有が可能かどうかの判定を行い、共有できない場合、ネットワークエラーとする
- Access-Control-Allow-Methods ヘッダー があり、パースできない場合、ネットワークエラーとする
- Access-Control-Allow-Headers ヘッダー があり、パースできない場合、ネットワークエラーとする
- Access-Control-Allow-Methods ヘッダー に値がある場合、その値のいずれともリクエストメソッドが一致しない場合、ネットワークエラーとする
- Access-Control-Allow-Headers ヘッダー に値がある場合、その値のいずれか または 単純なヘッダー のどちらとも一致しない場合、ネットワークエラーとする
- Access-Control-Max-Age ヘッダー がある場合、プリフライト 結果 キャッシュ の max-age を設定する
- Access-Control-Allow-Methods の値ごとに プリフライト 結果 キャッシュ を作成
- Access-Control-Allow-Headers の値ごとに プリフライト 結果 キャッシュ を作成
リソース共有が可能かどうかの判定
- Access-Control-Allow-Origin ヘッダー の値が 0 または 1 より多い 場合 (= 1 以外の場合)、false を返却して終了
- Access-Control-Allow-Origin ヘッダー の値が "*" かつ Access-Control-Allow-Credentials ヘッダー の値が "true" 以外の場合、true を返却して終了
- Access-Control-Allow-Origin ヘッダー の値が Origin ヘッダー に指定した値 と大文字小文字を区別して一致しない場合、 false を返して終了
- Access-Control-Allow-Credentials ヘッダー の値が "true" かつ Access-Control-Allow-Credentials ヘッダーの値が 0 または 1 より多い場合 (= 1 以外の場合)、 false を返却して終了
- Access-Control-Allow-Credentials ヘッダー の値が "true" でない場合、 false を返して終了
- true を返却
プリフライト 結果 キャッシュ
プリフライトを行い、成功した場合、その結果をクライアント(ブラウザ)にキャッシュします。
- origin
- 生成元ドメイン名
- url
- リクエストURL
- max-age
- Access-Control-Max-Age ヘッダーの値
- credentials
- 認証情報を利用するかどうか(クッキーを利用するかどうか)
- method
- Access-Control-Allow-Methods ヘッダーの値
- header
- Access-Control-Allow-Headers ヘッダーの値
参考記事
最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!