オリジン間リソース共有 (Cross-Origin Resource Sharing) (CORS) は、追加の HTTP ヘッダーを使用して、あるオリジン (ドメイン) で動作しているウェブアプリケーションに、異なるオリジンのサーバーにある選択されたリソースへのアクセスを許可することができる仕組みです。ウェブアプリケーションは、自分のオリジンとは異なるオリジン (ドメイン、プロトコル、ポート番号) からリソースをリクエストするとき、オリジン間 HTTP リクエストを発行します。

オリジン間リクエストの一例: http://domain-a.com で提供されているウェブアプリケーションのフロントエンド JavaScript コードが XMLHttpRequest を使用して http://api.domain-b.com/data.json へリクエストを行う場合。

セキュリティ上の理由から、ブラウザーは、スクリプトによって開始されるオリジン間 HTTP リクエストを制限しています。例えば、 XMLHttpRequestFetch API同一オリジンポリシー (same-origin policy) に従います。つまり、これらの API を使用するウェブアプリケーションは、そのアプリケーションが読み込まれたのと同じオリジンからのみ HTTP リソースのリクエストを行うことができ、それ以外のオリジンからの場合は正しい CORS ヘッダーを含んでいることが必要です。

CORS の仕組みは、安全なオリジン間のリクエストとブラウザー・ウェブサーバー間のデータ転送を支援します。最近のブラウザーは、オリジン間 HTTP リクエストのリスクの緩和に役立つよう、 XMLHttpRequestFetch などの API コンテナーで CORS を使用します。

この記事を読むべき人

本当に、誰でもです。

もっと具体的に言えば、この記事はウェブ管理者、サーバー開発者、フロントエンド開発者向けです。最近のブラウザーはヘッダーやポリシーの強制を含む、オリジン間共有のクライアント側コンポーネントを扱います。しかしこの新しい標準仕様は、サーバーが新たなリクエストヘッダーやレスポンスヘッダーを扱わなければならないことを意味します。サーバー開発者向けには、サーバーの観点によるオリジン間共有 (PHP コードスニペット付き) についての議論を合わせてお読みください。

CORS を使用したリクエストとは

このオリジン間共有仕様は、以下のようなサイト間 HTTP リクエストを可能にするために使用します。

この記事では、オリジン間リソース共有の全般的な説明と併せて、 HTTP ヘッダーの要件についても説明します。

機能概要

オリジン間リソース共有の仕様は、ウェブブラウザーを使用して情報を読み取ることを許可された一連のオリジンをサーバーが記述することができる、新たな HTTP ヘッダーを追加することによって作用します。加えて仕様書では、サーバーの情報に副作用を引き起こすことがある HTTP のリクエストメソッド (特に GET 以外の HTTP メソッドや、特定の MIME タイプを伴う POST の使い方) のために、ブラウザーが HTTP の OPTIONS リクエストメソッドを用いて、あらかじめリクエストの「プリフライト」 (サーバーから対応するメソッドの一覧を収集すること) を行い、サーバーの「認可」のもとに実際のリクエストを実際の HTTP リクエストメソッドにより送信することを指示しています。サーバーはリクエスト時に「資格情報」 (クッキーや HTTP 認証データを含む) を送信するべきかをクライアントに通知することもできます。

CORS は様々なエラーで失敗することがありますが、セキュリティ上の理由から、何が悪かったのかについて JavaScript のコードから知ることができないよう定められています。コードからはエラーが発生したということしか分かりません。何が悪かったのかを具体的に知ることができる唯一の方法は、ブラウザーのコンソールで詳細を見ることです。

以降の章ではシナリオの説明に加え、 HTTP ヘッダーの使い方の詳細も提供します。

アクセス制御シナリオの例

ここでは、オリジン間リソース共有がどのように動作するかを説明する3つのシナリオを示します。これらの例はすべて XMLHttpRequest オブジェクトを用いており、アクセス制御に対応するブラウザーで、サイトをまたいでアクセスを行うために使用できます。

本章にある JavaScript のスニペット (およびサイト間リクエストを適切に処理するサーバー側コードの実例) は http://arunranga.com/examples/access-control/ の "in action" にあり、サイト間の XMLHttpRequest に対応するブラウザーで動作するでしょう。

サーバー側から見た Cross-Origin Resource Sharing の説明 (PHP のコードスニペットを含む) は Server-Side Access Control (CORS) の記事にあります。

単純リクエスト

リクエストによっては CORS プリフライトを引き起こさないものがあります。これをこの記事では「単純リクエスト」と呼んでいますが、 (CORS を定義している) Fetch 仕様書ではこの用語を使用していません。 CORS プリフライトを引き起こさないリクエスト (いわゆる「単純リクエスト」) は、以下すべての条件を満たすものです。

メモ: これらはウェブコンテンツが発行可能になっているサイト間リクエストと同じ種類のものであり、サーバーが適切なヘッダーを送信しなければレスポンスデータは送信元へ送られません。従ってクロスサイトリクエストフォージェリ対策をしているサイトは、 HTTP アクセス制限について新たに心配することはありません。
メモ: WebKit Nightly および Safari Technology Preview は、 Accept, Accept-Language, Content-Language ヘッダーの値に追加の制限を掛けています。これらのヘッダーが「標準外」の値の場合、 WebKit/Safari はそのリクエストが「単純リクエスト」の条件に合うとは判断しません。 WebKit/Safari がこれらのヘッダーのどの値を「標準外」と判断するかについては、 WebKit のバグ、 Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-Language, Allow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS, Switch to a blacklist model for restricted Accept headers in simple CORS requests にしか記述されていません。これは仕様の一部ではないので、他のブラウザーはこの追加の制限を実装していません。

例えば、ドメイン http://foo.example にあるウェブコンテンツがドメイン http://bar.other にあるコンテンツを呼び出したいと仮定します。以下のようなコードが foo.example 内の JavaScript で使用されるかもしれません。

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/public-data/';
   
function callOtherDomain() {
  if(invocation) {    
    invocation.open('GET', url, true);
    invocation.onreadystatechange = handler;
    invocation.send(); 
  }
}

これは、特権を扱うために CORS ヘッダーを使用して、クライアントとサーバーの間で簡単なデータ交換を行います。

この場合、ブラウザーがサーバーに何を送信し、サーバーが何を返すかを見てみましょう。

GET /resources/public-data/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://foo.example/examples/access-control/simpleXSInvocation.html
Origin: http://foo.example


HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 00:23:53 GMT
Server: Apache/2.0.61 
Access-Control-Allow-Origin: *
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Transfer-Encoding: chunked
Content-Type: application/xml

[XML データ]

1-10行目は送信されたヘッダーです。ここに記載した HTTP ヘッダーの中で、10行目の Origin ヘッダーが重要で、呼び出しがドメイン http://foo.example にあるコンテンツから来たことを表しています。

13-22行目はドメイン http://bar.other にあるサーバーからの HTTP レスポンスです。レスポンスでは、サーバーが16行目で Access-Control-Allow-Origin: ヘッダーを返しています。 Origin: ヘッダーと Access-Control-Allow-Origin: ヘッダーの使用は、もっともシンプルな形のアクセス制御プロトコルを表します。この場合、サーバーはリソースがすべてのドメインからサイト間方式でアクセスできることを意味する Access-Control-Allow-Origin: * を伴って返答しています。 http://bar.other のリソース所有者がリソースへのアクセスを http://foo.example からだけに制限したい場合は、以下のように返答します。

Access-Control-Allow-Origin: http://foo.example

ここで、 http://foo.example (前出の10行目のようにリクエストの ORIGIN: ヘッダーで識別されます) 以外にサイト間方式でリソースにアクセスできるドメインはないことに注意してください。 Access-Control-Allow-Origin ヘッダーには、リクエストの Origin ヘッダーで送られた値を含めてください。

プリフライトリクエスト

「単純リクエスト」 (前述) とは異なり、「プリフライト」リクエストは始めに OPTIONS メソッドによるリクエストを他のドメインにあるリソースに向けて送り、実際のリクエストを送信しても安全かどうかを確かめます。サイト間リクエストはユーザーデータに影響を与える可能性があるため、このようにプリフライトを行います。

特に、以下の条件のいずれかが満たされたとき、プリフライトリクエストが用いられます。

メモ: WebKit Nightly および Safari Technology Preview は、 Accept, Accept-Language, Content-Language ヘッダーの値に追加の制限を掛けています。これらのヘッダーが「標準外」の値の場合、 WebKit/Safari はプリフライトリクエストを用います。 WebKit/Safari がこれらのヘッダーのどの値を「標準外」と判断するかについては、 WebKit のバグ、 Require preflight for non-standard CORS-safelisted request headers Accept, Accept-Language, and Content-Language, Allow commas in Accept, Accept-Language, and Content-Language request headers for simple CORS, Switch to a blacklist model for restricted Accept headers in simple CORS requests にしか記述されていません。これは使用の一部ではないので、他のブラウザーはこの追加の制限を実装していません。

以下の例は、プリフライトが行われるリクエストの例です。

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/post-here/';
var body = '<?xml version="1.0"?><person><name>Arun</name></person>';
    
function callOtherDomain(){
  if(invocation)
    {
      invocation.open('POST', url, true);
      invocation.setRequestHeader('X-PINGOTHER', 'pingpong');
      invocation.setRequestHeader('Content-Type', 'application/xml');
      invocation.onreadystatechange = handler;
      invocation.send(body); 
    }
}

......

上記の例の3行目では、8行目の POST で送信する XML の本体を作成しています。また 9 行目では、"カスタム" (標準外) HTTP リクエストヘッダー (X-PINGOTHER: pingpong) を設定しています。このようなヘッダーは HTTP/1.1 プロトコルに含まれていませんが、ウェブアプリケーションでは一般的に便利なものです。リクエスト (POST) で application/xml の Content-Type を使用しており、かつカスタムヘッダーを設定しているため、このリクエストではプリフライトを行います。

(メモ: 後述するように、実際の POST リクエストには Access-Control-Request-* ヘッダーが含まれず、 OPTIONS リクエストのみで必要になります。)

クライアントとサーバーとの間のやりとりの全容を見てみましょう。最初のやり取りはプリフライトリクエスト/レスポンスです。

OPTIONS /resources/post-here/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Origin: http://foo.example
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type


HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:39 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 0
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain

プリフライトリクエストが完了したら、実際のリクエストを送ります。

POST /resources/post-here/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
X-PINGOTHER: pingpong
Content-Type: text/xml; charset=UTF-8
Referer: http://foo.example/examples/preflightInvocation.html
Content-Length: 55
Origin: http://foo.example
Pragma: no-cache
Cache-Control: no-cache

<?xml version="1.0"?><person><name>Arun</name></person>


HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:15:40 GMT
Server: Apache/2.0.61 (Unix)
Access-Control-Allow-Origin: http://foo.example
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 235
Keep-Alive: timeout=2, max=99
Connection: Keep-Alive
Content-Type: text/plain

[Some GZIP'd payload]

上記の1-12行目は OPTIONS メソッドによるプリフライトを表します。ブラウザーは上記で使用された JavaScript コードで使用しているリクエストの引数に基づいて、プリフライトの送信が必要であることを判断します。これによりサーバーは実際のリクエストの引数によって送られるリクエストを受け入れ可能かをレスポンスできます。 OPTIONS はサーバーから付加的な情報を得るために用いる HTTP/1.1 のメソッドであり、また安全なメソッド、つまりリソースを変更するためには使用できないメソッドです。 OPTIONS リクエストと合わせて、他にリクエストヘッダーを2つ送信していることに注意してください (それぞれ10行目と11行目です)。

Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-PINGOTHER, Content-Type

Access-Control-Request-Method ヘッダーは、プリフライトリクエストの一部として、実際のリクエストが POST リクエストメソッドで送られることをサーバーに通知します。 Access-Control-Request-Headers ヘッダーは、実際のリクエストにカスタムヘッダーである X-PINGOTHER および Content-Type が含まれることをサーバーに通知します。ここでサーバーは、この状況下でリクエストの受け入れを望むかを判断する機会があります。

上記の14-26行目はサーバーが返すレスポンスであり、リクエストメソッド (POST) とリクエストヘッダー (X-PINGOTHER) を受け入れられることを示しています。特に、17-20行目を見てみましょう。

Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Methods: POST, GET
Access-Control-Allow-Headers: X-PINGOTHER, Content-Type
Access-Control-Max-Age: 86400

サーバーは Access-Control-Allow-Methods を返しており、これは当該リソースへの問い合わせで POST 及び GET が実行可能なメソッドであることを伝えます。なお、このヘッダーはレスポンスヘッダーの Allow と似ていますが、アクセス制御でのみ使用されることに注意してください。

またサーバーは、 Access-Control-Allow-HeadersX-PINGOTHER の値で送信し、これが実際のリクエストで使用されるヘッダーであることを承認しています。 Access-Control-Allow-Methods と同様に、 Access-Control-Allow-Headers は受け入れ可能なヘッダーをコンマ区切りのリストで表します。

最後に Access-Control-Max-Age は、プリフライトリクエストを再び送らなくてもいいように、プリフライトのレスポンスをキャッシュしてよい時間を秒数で与えます。この例では86400秒、つまり24時間です。なお、ブラウザーは個々に内部の上限値を持っており、 Access-Control-Max-Age が上回った場合に制限を掛けます。

プリフライトリクエストとリダイレクト

多くのブラウザーは現在、下記のようなプリフライトリクエストのリダイレクトに対応していません。プリフライトリクエストにリダイレクトが発生すると、多くのブラウザーは以下のようなエラーメッセージを報告します。

リクエストがプリフライトを必要とするオリジン間リクエストで許可されていない 'https://example.com/foo' にリダイレクトされました。

リクエストにはプリフライトが必要で、オリジン間のリダイレクトは許可されていません

もともと CORS プロトコルはそのような振る舞いを要求していましたが、その後で必要がないと変更されました。しかし、多くのブラウザーはまだ変更を実装しておらず、もともと要求されていた振る舞いに従っています。

ですから、ブラウザーが仕様に追いつくまで、以下の一方もしくは両方を行うことでこの制限を回避することができます。

  • リクエストが生成されるサーバーの制御権を持っているのであれば、サーバ側の振る舞いを変更して、プリフライトが発生しないようにするか、リダイレクトが発生しないようにする
  • リクエストをプリフライトを起こさない単純リクエストなどに変更する

しかし、これらの変更ができない場合は、以下のような他の方法を使うこともできます。

  1. 単純リクエストを行い (Fetch API の Response.url または XMLHttpRequest.responseURL を使用して)、実際のプリフライトリクエストが転送される先を特定する。
  2. 最初のステップの Response.url または XMLHttpRequest.responseURL で得た URL を使用して、もう一つのリクエスト (「本当の」リクエスト) を行う。

ただし、リクエストに Authorization ヘッダーが存在するためにプリフライトを引き起こすリクエストの場合、上記の手順を使用して制限を回避することはできません。リクエストが行われているサーバーを制御できない限り、まったく回避することはできません。

資格情報を含むリクエスト

XMLHttpRequestFetch と CORS の両方によって明らかになる最も興味深い機能は、 HTTP クッキーと HTTP 認証情報によってわかる「資格情報を含む」リクエストを作成することができることです。既定では、サイト間の XMLHttpRequest" または Fetch の呼び出しにおいて、ブラウザーは資格情報を送信しませんXMLHttpRequest" オブジェクトまたは Request のコンストラクターの呼び出し時に、特定のフラグを設定する必要があります。

以下の例では http://foo.example から読み込まれた元のコンテンツが、 http://bar.other にあるリソースに対してクッキーを設定したシンプルな GET リクエストを行います。 foo.example のコンテンツは以下のような JavaScript を含んでいるかもしれません。

var invocation = new XMLHttpRequest();
var url = 'http://bar.other/resources/credentialed-content/';
    
function callOtherDomain(){
  if(invocation) {
    invocation.open('GET', url, true);
    invocation.withCredentials = true;
    invocation.onreadystatechange = handler;
    invocation.send(); 
  }
}

7行目で、クッキー付きで呼び出しを行うために XMLHttpRequest に設定する必要があるフラグ、 withCredentials という真偽値型の値を示しています。既定では、クッキーなしで呼び出しが行われます。これは単純な GET リクエストなのでプリフライトは行いませんが、ブラウザーは Access-Control-Allow-Credentials: true ヘッダーを持たないレスポンスを拒否し、ウェブコンテンツを呼び出すレスポンスを作成しないでしょう。

以下はクライアントとサーバーとの間のやりとりの例です。

GET /resources/access-control-with-credentials/ HTTP/1.1
Host: bar.other
User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1b3pre) Gecko/20081130 Minefield/3.1b3pre
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Referer: http://foo.example/examples/credential.html
Origin: http://foo.example
Cookie: pageAccess=2


HTTP/1.1 200 OK
Date: Mon, 01 Dec 2008 01:34:52 GMT
Server: Apache/2.0.61 (Unix) PHP/4.4.7 mod_ssl/2.0.61 OpenSSL/0.9.7e mod_fastcgi/2.4.2 DAV/2 SVN/1.4.2
X-Powered-By: PHP/5.2.6
Access-Control-Allow-Origin: http://foo.example
Access-Control-Allow-Credentials: true
Cache-Control: no-cache
Pragma: no-cache
Set-Cookie: pageAccess=3; expires=Wed, 31-Dec-2008 01:34:53 GMT
Vary: Accept-Encoding, Origin
Content-Encoding: gzip
Content-Length: 106
Keep-Alive: timeout=2, max=100
Connection: Keep-Alive
Content-Type: text/plain


[text/plain payload]

11行目に http://bar.other 向けのクッキーが含まれていますが、bar.other が Access-Control-Allow-Credentials: true (19行目) をレスポンスに含めなければ、レスポンスは無視されウェブコンテンツで使用できません。

資格情報付きリクエストとワイルドカード

資格情報を含むリクエストに対するレスポンスの時、サーバーは Access-Control-Allow-Origin ヘッダーで "*" ワイルドカードではなくオリジンを指定しなければなりません

上記の例のリクエストヘッダーは Cookie ヘッダーを含んでいるため、 Access-Control-Allow-Origin ヘッダーが "*" であったらリクエストは失敗します。 Access-Control-Allow-Origin ヘッダーの値が "*" ワイルドカードではなく "http://foo.example" (実際のオリジン) なので、ウェブコンテンツの呼び出しに対して資格情報を意識したコンテンツが返ります。

なお、上記の例の中にある Set-Cookie レスポンスヘッダーは、将来のクッキーの設定も行ないます。失敗した場合、 (使われている API によりますが) 例外が発生します。

サードパーティーのクッキー

CORS のレスポンスに設定されたクッキーは、サードパーティーのクッキーに関する通常のポリシーに従います。上記の例では、ページは foo.example から読み込まれていますが、22行目のクッキーは bar.other から送られているので、ユーザーがブラウザーでサードパーティーのクッキーをすべて拒否するよう設定していた場合は保存されません。

HTTP レスポンスヘッダー

ここではオリジン間リソース共有の仕様書で定義されている、アクセス制御のためにサーバーが返す HTTP レスポンスヘッダーを掲載します。前の章では、これらの実際の動作の概要を説明しました。

Access-Control-Allow-Origin

返却されるリソースには、以下のような構文で1つの Access-Control-Allow-Origin ヘッダーがつくことがあります。

Access-Control-Allow-Origin: <origin> | *

Access-Control-Allow-Origin は、リソースへのアクセスを許可するオリジンをブラウザーに伝えるための単一のオリジン、または — 資格情報を含まないリクエストにおいては — どのオリジンにもリソースへのアクセスを許可することをブラウザーに伝えるワイルドカード "*" のどちらかを指定することができます。

例えば、 http://mozilla.org のオリジンからのコードにリソースへのアクセスを許可するには、次のように指定します。

Access-Control-Allow-Origin: http://mozilla.org

サーバーがワイルドカード "*" ではない単一のオリジンを指定した場合は、サーバーは Vary レスポンスヘッダーに Origin も含めて、サーバーのレスポンスが Origin リクエストヘッダーの値によって変化することをクライアントに示してください。

Access-Control-Expose-Headers

Access-Control-Expose-Headers ヘッダーは、以下の例のようにブラウザーがアクセスを許可されるサーバーのホワイトリストを示すことができます。

Access-Control-Expose-Headers: X-My-Custom-Header, X-Another-Custom-Header

これは、ブラウザーに対して X-My-Custom-Header および X-Another-Custom-Header ヘッダーを許可します。

Access-Control-Max-Age

このヘッダーはプリフライトリクエストの結果をキャッシュしてよい時間を示します。プリフライトリクエストの例は、前出の例をご覧ください。

Access-Control-Max-Age: <delta-seconds>

delta-seconds 引数は、結果をキャッシュしてよい時間を秒単位で示します。

Access-Control-Allow-Credentials

Access-Control-Allow-Credentialscredentials フラグが真であるときに、リクエストへのレスポンスを開示してよいか否かを示します。プリフライトリクエストのレスポンスの一部として用いられたときは、実際のリクエストで資格情報を使用してよいか否かを示します。単純な GET リクエストはプリフライトを行いませんので、リソースへのリクエストが資格情報付きで行われた場合にリソースと共にこのヘッダーを返さなければ、レスポンスはブラウザーによって無視され、ウェブコンテンツに返らないことに注意してください。

Access-Control-Allow-Credentials: true

資格情報付きのリクエストは前に説明したとおりです。

Access-Control-Allow-Methods

Access-Control-Allow-Methods ヘッダーは、リソースへのアクセス時に許可するメソッドを指定します。これはプリフライトリクエストのレスポンスで用いられます。リクエストのプリフライトを行う条件については前述のとおりです。

Access-Control-Allow-Methods: <method>[, <method>]*

ブラウザーにこのヘッダーを送信する例を含む、プリフライトリクエストの例は 前述のとおりです

Access-Control-Allow-Headers

Access-Control-Allow-Headers ヘッダーは、実際のリクエストでどの HTTP ヘッダーを使用できるかを示すために、プリフライトリクエストのレスポンスで使用します。

Access-Control-Allow-Headers: <field-name>[, <field-name>]*

HTTP リクエストヘッダー

この節では、 HTTP リクエストを発行する際、オリジン間リソース共有機能を利用するためにクライアントが使用できるヘッダーの一覧を掲載します。なお、これらのヘッダーはサーバーの呼び出し時に設定されます。サイト間 XMLHttpRequest の機能を使用する開発者は、オリジン間リソース共有のヘッダーをプログラムで設定する必要はありません。

Origin

Origin ヘッダーはサイト間のアクセスリクエストやプリフライトリクエストのオリジンを示します。

Origin: <origin>

origin は、リクエストを開始したサーバーを示す URI です。ここにパス情報は含めず、サーバー名だけにします。

メモ: origin は空文字列にすることができます。これは、例えばオリジンが data URL である場合などに有用です。

すべてのアクセス制御リクエストにおいて、 Origin ヘッダーは常に送信されることに注意してください。

Access-Control-Request-Method

Access-Control-Request-Method はプリフライトリクエストを発信する際に、実際のリクエストを行う際に使用する HTTP メソッドをサーバーに知らせるために使用します。

Access-Control-Request-Method: <method>

使用例は前出のとおりです

Access-Control-Request-Headers

Access-Control-Request-Headers ヘッダーは、プリフライトリクエストを発信する際に、実際のリクエストを行う際に使用する HTTP ヘッダーをサーバーに知らせるために使用します。

Access-Control-Request-Headers: <field-name>[, <field-name>]*

使用例は 前出のとおりです

仕様書

仕様書 状態 備考
Fetch
CORS の定義
現行の標準 W3C CORS 仕様書を置き換える新しい定義です。

ブラウザーの対応

Update compatibility data on GitHub
デスクトップモバイル
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewAndroid 版 ChromeEdge MobileAndroid 版 FirefoxAndroid 版 OperaiOS 版 SafariSamsung Internet
基本対応Chrome 完全対応 4Edge 完全対応 12Firefox 完全対応 3.5IE 完全対応 10Opera 完全対応 12Safari 完全対応 4WebView Android 完全対応 2Chrome Android 完全対応 ありEdge Mobile 完全対応 ありFirefox Android 完全対応 4Opera Android 完全対応 12Safari iOS 完全対応 3.2Samsung Internet Android 完全対応 あり

凡例

完全対応  
完全対応

互換性のメモ

  • Internet Explorer 8 および 9 は XDomainRequest オブジェクトで CORS を提供していますが、完全な実装は IE 10 で行っています。
  • Firefox 3.5 よりサイト間の XMLHttpRequests とウェブフォントのサポートを始めていましたが、ある種のリクエストは後のバージョンまで制限されていました。具体的には Firefox 7 から Web GL テクスチャのサイト間 HTTP リクエスト、 Firefox 9 では drawImage を用いた Canvas への画像描画のサポートを始めました。

関連情報