From 0d4eb6823d60b7b48bcfd972d10e1032af60307e Mon Sep 17 00:00:00 2001 From: Masahiro FUJIMOTO Date: Thu, 23 Sep 2021 12:57:02 +0900 Subject: Web/HTTP/CORS を Markdown 化 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- files/ja/web/http/cors/index.html | 502 -------------------------------------- files/ja/web/http/cors/index.md | 502 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 502 insertions(+), 502 deletions(-) delete mode 100644 files/ja/web/http/cors/index.html create mode 100644 files/ja/web/http/cors/index.md (limited to 'files/ja') diff --git a/files/ja/web/http/cors/index.html b/files/ja/web/http/cors/index.html deleted file mode 100644 index 33d046aaed..0000000000 --- a/files/ja/web/http/cors/index.html +++ /dev/null @@ -1,502 +0,0 @@ ---- -title: オリジン間リソース共有 (CORS) -slug: Web/HTTP/CORS -tags: - - AJAX - - CORS - - Fetch - - Fetch API - - HTTP - - HTTP アクセス制御 - - Security - - XMLHttpRequest - - 'l10n:priority' - - オリジン間リソース共有 - - セキュリティ - - 同一オリジンポリシー -translation_of: Web/HTTP/CORS ---- -
{{HTTPSidebar}}
- -

オリジン間リソース共有 (Cross-Origin Resource Sharing) ({{Glossary("CORS")}}) は、追加の {{Glossary("HTTP")}} ヘッダーを使用して、ある{{glossary("origin", "オリジン")}}で動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組みです。ウェブアプリケーションは、自分とは異なるオリジン (ドメイン、プロトコル、ポート番号) にあるリソースをリクエストするとき、オリジン間 HTTP リクエストを実行します。

- -

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

- -

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

- -

- -

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

- -

この記事を読むべき人

- -

誰もが読むべきです。

- -

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

- -

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

- -

このオリジン間共有仕様は、以下のようなサイト間 HTTP リクエストを有効にすることができます。

- - - -

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

- -

機能概要

- -

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

- -

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

- -

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

- -

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

- -

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

- -

サーバー側から見たオリジン間リソース共有の説明 (PHP のコードスニペットを含む) は Server-Side Access Control (CORS) の記事にあります。

- -

単純リクエスト

- -

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

- - - -
注: これらはウェブコンテンツが発行可能になっているサイト間リクエストと同じ種類のものであり、サーバーが適切なヘッダーを送信しなければレスポンスデータは送信元へ送られません。従ってクロスサイトリクエストフォージェリ対策をしているサイトは、 HTTP アクセス制限について新たに心配することはありません。
- -
-

注: WebKit Nightly および Safari Technology Preview は、 {{HTTPHeader("Accept")}}, {{HTTPHeader("Accept-Language")}}, {{HTTPHeader("Content-Language")}} ヘッダーの値に追加の制限を掛けています。これらのヘッダーが「標準外」の値の場合、 WebKit/Safari はそのリクエストが「単純リクエスト」の条件に合うとは判断しません。 WebKit/Safari がこれらのヘッダーのどの値を「標準外」と判断するかについては、以下の WebKit のバグを除いて文書化されていません。

- - - -

これは仕様の一部ではないので、他のブラウザーはこの追加の制限を実装していません。

-
- -

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

- -
const xhr = new XMLHttpRequest();
-const url = 'https://bar.other/resources/public-data/';
-
-xhr.open('GET', url);
-xhr.onreadystatechange = someHandler;
-xhr.send();
-
- -

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

- -

- -

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

- -
GET /resources/public-data/ HTTP/1.1
-Host: bar.other
-User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
-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
-Connection: keep-alive
-Origin: https://foo.example
-
- -

特筆すべきリクエストヘッダーは {{HTTPHeader("Origin")}} であり、呼び出しが https://foo.example から来たことを表します。

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

レスポンスでは、サーバーが {{HTTPHeader("Access-Control-Allow-Origin")}} ヘッダーを返信しています。 {{HTTPHeader("Origin")}} ヘッダーと {{HTTPHeader("Access-Control-Allow-Origin")}} ヘッダーの使用は、最も単純なアクセス制御プロトコルを表しています。この場合、サーバーは Access-Control-Allow-Origin: * を返しており、これはそのリソースがすべてのドメインからアクセスできることを意味します。 https://bar.other にあるリソースの所有者が、リソースへの制限を https://foo.example からのリクエストのみに制限したいと考えていた場合は、以下のように送信します。

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

https://foo.example 以外のドメインはすべて、サイト間の方法でリソースにアクセスすることがサイト間の方法でリソースにアクセスすることができなくなりました。リソースへのアクセスを許可するには、 Access-Control-Allow-Origin ヘッダーに、リクエストの Origin ヘッダーの中で送信された値を含めてください。

- -

プリフライトリクエスト

- -

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

- -

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

- -
const xhr = new XMLHttpRequest();
-xhr.open('POST', 'https://bar.other/resources/post-here/');
-xhr.setRequestHeader('X-PINGOTHER', 'pingpong');
-xhr.setRequestHeader('Content-Type', 'application/xml');
-xhr.onreadystatechange = handler;
-xhr.send('<person><name>Arun</name></person>');
-
- -

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

- -

- -
-

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

-
- -

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

- -
OPTIONS /doc HTTP/1.1
-Host: bar.other
-User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
-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
-Connection: keep-alive
-Origin: http://foo.example
-Access-Control-Request-Method: POST
-Access-Control-Request-Headers: X-PINGOTHER, Content-Type
-
-
-HTTP/1.1 204 No Content
-Date: Mon, 01 Dec 2008 01:15:39 GMT
-Server: Apache/2
-Access-Control-Allow-Origin: https://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
-Keep-Alive: timeout=2, max=100
-Connection: Keep-Alive
-
- -

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

- -
POST /doc HTTP/1.1
-Host: bar.other
-User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
-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
-Connection: keep-alive
-X-PINGOTHER: pingpong
-Content-Type: text/xml; charset=UTF-8
-Referer: https://foo.example/examples/preflightInvocation.html
-Content-Length: 55
-Origin: https://foo.example
-Pragma: no-cache
-Cache-Control: no-cache
-
-<person><name>Arun</name></person>
-
-
-HTTP/1.1 200 OK
-Date: Mon, 01 Dec 2008 01:15:40 GMT
-Server: Apache/2
-Access-Control-Allow-Origin: https://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 XML payload]
-
- -

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

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

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

- -

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

- -
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
- -

サーバーは Access-Control-Allow-Methods を返しており、これは当該リソースへの問い合わせで POST および GET が実行可能なメソッドであることを伝えます。なお、このヘッダーはレスポンスヘッダーの {{HTTPHeader("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 の {{domxref("Response.url")}} または {{domxref("XMLHttpRequest.responseURL")}} を使用して)、実際のプリフライトリクエストが転送される先を特定する。
  2. -
  3. 最初のステップの Response.url または XMLHttpRequest.responseURL で得た URL を使用して、もう一つのリクエスト (「本当の」リクエスト) を行う。
  4. -
- -

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

- -

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

- -

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

- -

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

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

- -

- -

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

- -
GET /resources/credentialed-content/ HTTP/1.1
-Host: bar.other
-User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
-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
-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
-Access-Control-Allow-Origin: https://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]
-
- -

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

- -

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

- -

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

- -

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

- -

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

- -

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

- -

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

- -

HTTP レスポンスヘッダー

- -

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

- -

Access-Control-Allow-Origin

- -

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

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

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

- -

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

- -
Access-Control-Allow-Origin: https://mozilla.org
-Vary: Origin
- -

サーバーがワイルドカード "*" ではなく (ホワイトリストの一部としてリクエストするオリジンに基づいて動的に変更される可能性がある) 単一のオリジンを指定した場合は、サーバーは {{HTTPHeader("Vary")}} レスポンスヘッダーに Origin も含めて、サーバーのレスポンスが {{HTTPHeader("Origin")}} リクエストヘッダーの値によって変化することをクライアントに示してください。

- -

Access-Control-Expose-Headers

- -

{{HTTPHeader("Access-Control-Expose-Headers")}} ヘッダーは、ブラウザーがアクセスを許可されるサーバーのホワイトリストにあるヘッダーを示すことができます。

- -
Access-Control-Expose-Headers: <header-name>[, <header-name>]*
-
- -

例えば、以下のようになります。

- -
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

- -

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

- -
Access-Control-Allow-Credentials: true
-
- -

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

- -

Access-Control-Allow-Methods

- -

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

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

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

- -

Access-Control-Allow-Headers

- -

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

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

HTTP リクエストヘッダー

- -

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

- -

Origin

- -

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

- -
Origin: <origin>
-
- -

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

- -
注: origin の値は null または URI にすることができます。
- -

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

- -

Access-Control-Request-Method

- -

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

- -
Access-Control-Request-Method: <method>
-
- -

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

- -

Access-Control-Request-Headers

- -

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

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

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

- -

仕様書

- - - - - - - - - - - - - - -
仕様書状態備考
{{SpecName('Fetch', '#cors-protocol', 'CORS')}}{{Spec2('Fetch')}}W3C CORS 仕様書を置き換える新しい定義です。
- -

ブラウザーの互換性

- -

{{Compat("http.headers.Access-Control-Allow-Origin")}}

- -

互換性のメモ

- -

Internet Explorer 8 および 9 は XDomainRequest オブジェクトで CORS を提供していますが、完全な実装は IE 10 で行っています。

- -

関連情報

- - diff --git a/files/ja/web/http/cors/index.md b/files/ja/web/http/cors/index.md new file mode 100644 index 0000000000..234fb204f7 --- /dev/null +++ b/files/ja/web/http/cors/index.md @@ -0,0 +1,502 @@ +--- +title: オリジン間リソース共有 (CORS) +slug: Web/HTTP/CORS +tags: + - AJAX + - CORS + - Fetch + - Fetch API + - HTTP + - HTTP アクセス制御 + - Security + - XMLHttpRequest + - l10n:priority + - オリジン間リソース共有 + - セキュリティ + - 同一オリジンポリシー +translation_of: Web/HTTP/CORS +--- +
{{HTTPSidebar}}
+ +

オリジン間リソース共有 (Cross-Origin Resource Sharing) ({{Glossary("CORS")}}) は、追加の {{Glossary("HTTP")}} ヘッダーを使用して、ある{{glossary("origin", "オリジン")}}で動作しているウェブアプリケーションに、異なるオリジンにある選択されたリソースへのアクセス権を与えるようブラウザーに指示するための仕組みです。ウェブアプリケーションは、自分とは異なるオリジン (ドメイン、プロトコル、ポート番号) にあるリソースをリクエストするとき、オリジン間 HTTP リクエストを実行します。

+ +

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

+ +

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

+ +

+ +

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

+ +

この記事を読むべき人

+ +

誰もが読むべきです。

+ +

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

+ +

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

+ +

このオリジン間共有仕様は、以下のようなサイト間 HTTP リクエストを有効にすることができます。

+ + + +

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

+ +

機能概要

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

サーバー側から見たオリジン間リソース共有の説明 (PHP のコードスニペットを含む) は Server-Side Access Control (CORS) の記事にあります。

+ +

単純リクエスト

+ +

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

+ + + +
注: これらはウェブコンテンツが発行可能になっているサイト間リクエストと同じ種類のものであり、サーバーが適切なヘッダーを送信しなければレスポンスデータは送信元へ送られません。従ってクロスサイトリクエストフォージェリ対策をしているサイトは、 HTTP アクセス制限について新たに心配することはありません。
+ +
+

注: WebKit Nightly および Safari Technology Preview は、 {{HTTPHeader("Accept")}}, {{HTTPHeader("Accept-Language")}}, {{HTTPHeader("Content-Language")}} ヘッダーの値に追加の制限を掛けています。これらのヘッダーが「標準外」の値の場合、 WebKit/Safari はそのリクエストが「単純リクエスト」の条件に合うとは判断しません。 WebKit/Safari がこれらのヘッダーのどの値を「標準外」と判断するかについては、以下の WebKit のバグを除いて文書化されていません。

+ + + +

これは仕様の一部ではないので、他のブラウザーはこの追加の制限を実装していません。

+
+ +

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

+ +
const xhr = new XMLHttpRequest();
+const url = 'https://bar.other/resources/public-data/';
+
+xhr.open('GET', url);
+xhr.onreadystatechange = someHandler;
+xhr.send();
+
+ +

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

+ +

+ +

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

+ +
GET /resources/public-data/ HTTP/1.1
+Host: bar.other
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
+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
+Connection: keep-alive
+Origin: https://foo.example
+
+ +

特筆すべきリクエストヘッダーは {{HTTPHeader("Origin")}} であり、呼び出しが https://foo.example から来たことを表します。

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

レスポンスでは、サーバーが {{HTTPHeader("Access-Control-Allow-Origin")}} ヘッダーを返信しています。 {{HTTPHeader("Origin")}} ヘッダーと {{HTTPHeader("Access-Control-Allow-Origin")}} ヘッダーの使用は、最も単純なアクセス制御プロトコルを表しています。この場合、サーバーは Access-Control-Allow-Origin: * を返しており、これはそのリソースがすべてのドメインからアクセスできることを意味します。 https://bar.other にあるリソースの所有者が、リソースへの制限を https://foo.example からのリクエストのみに制限したいと考えていた場合は、以下のように送信します。

+ +
Access-Control-Allow-Origin: https://foo.example
+ +

https://foo.example 以外のドメインはすべて、サイト間の方法でリソースにアクセスすることがサイト間の方法でリソースにアクセスすることができなくなりました。リソースへのアクセスを許可するには、 Access-Control-Allow-Origin ヘッダーに、リクエストの Origin ヘッダーの中で送信された値を含めてください。

+ +

プリフライトリクエスト

+ +

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

+ +

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

+ +
const xhr = new XMLHttpRequest();
+xhr.open('POST', 'https://bar.other/resources/post-here/');
+xhr.setRequestHeader('X-PINGOTHER', 'pingpong');
+xhr.setRequestHeader('Content-Type', 'application/xml');
+xhr.onreadystatechange = handler;
+xhr.send('<person><name>Arun</name></person>');
+
+ +

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

+ +

+ +
+

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

+
+ +

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

+ +
OPTIONS /doc HTTP/1.1
+Host: bar.other
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
+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
+Connection: keep-alive
+Origin: http://foo.example
+Access-Control-Request-Method: POST
+Access-Control-Request-Headers: X-PINGOTHER, Content-Type
+
+
+HTTP/1.1 204 No Content
+Date: Mon, 01 Dec 2008 01:15:39 GMT
+Server: Apache/2
+Access-Control-Allow-Origin: https://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
+Keep-Alive: timeout=2, max=100
+Connection: Keep-Alive
+
+ +

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

+ +
POST /doc HTTP/1.1
+Host: bar.other
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
+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
+Connection: keep-alive
+X-PINGOTHER: pingpong
+Content-Type: text/xml; charset=UTF-8
+Referer: https://foo.example/examples/preflightInvocation.html
+Content-Length: 55
+Origin: https://foo.example
+Pragma: no-cache
+Cache-Control: no-cache
+
+<person><name>Arun</name></person>
+
+
+HTTP/1.1 200 OK
+Date: Mon, 01 Dec 2008 01:15:40 GMT
+Server: Apache/2
+Access-Control-Allow-Origin: https://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 XML payload]
+
+ +

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

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

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

+ +

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

+ +
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
+ +

サーバーは Access-Control-Allow-Methods を返しており、これは当該リソースへの問い合わせで POST および GET が実行可能なメソッドであることを伝えます。なお、このヘッダーはレスポンスヘッダーの {{HTTPHeader("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 の {{domxref("Response.url")}} または {{domxref("XMLHttpRequest.responseURL")}} を使用して)、実際のプリフライトリクエストが転送される先を特定する。
  2. +
  3. 最初のステップの Response.url または XMLHttpRequest.responseURL で得た URL を使用して、もう一つのリクエスト (「本当の」リクエスト) を行う。
  4. +
+ +

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

+ +

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

+ +

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

+ +

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

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

+ +

+ +

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

+ +
GET /resources/credentialed-content/ HTTP/1.1
+Host: bar.other
+User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:71.0) Gecko/20100101 Firefox/71.0
+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
+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
+Access-Control-Allow-Origin: https://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]
+
+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

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

+ +

HTTP レスポンスヘッダー

+ +

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

+ +

Access-Control-Allow-Origin

+ +

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

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

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

+ +

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

+ +
Access-Control-Allow-Origin: https://mozilla.org
+Vary: Origin
+ +

サーバーがワイルドカード "*" ではなく (ホワイトリストの一部としてリクエストするオリジンに基づいて動的に変更される可能性がある) 単一のオリジンを指定した場合は、サーバーは {{HTTPHeader("Vary")}} レスポンスヘッダーに Origin も含めて、サーバーのレスポンスが {{HTTPHeader("Origin")}} リクエストヘッダーの値によって変化することをクライアントに示してください。

+ +

Access-Control-Expose-Headers

+ +

{{HTTPHeader("Access-Control-Expose-Headers")}} ヘッダーは、ブラウザーがアクセスを許可されるサーバーのホワイトリストにあるヘッダーを示すことができます。

+ +
Access-Control-Expose-Headers: <header-name>[, <header-name>]*
+
+ +

例えば、以下のようになります。

+ +
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

+ +

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

+ +
Access-Control-Allow-Credentials: true
+
+ +

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

+ +

Access-Control-Allow-Methods

+ +

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

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

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

+ +

Access-Control-Allow-Headers

+ +

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

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

HTTP リクエストヘッダー

+ +

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

+ +

Origin

+ +

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

+ +
Origin: <origin>
+
+ +

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

+ +
注: origin の値は null または URI にすることができます。
+ +

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

+ +

Access-Control-Request-Method

+ +

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

+ +
Access-Control-Request-Method: <method>
+
+ +

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

+ +

Access-Control-Request-Headers

+ +

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

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

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

+ +

仕様書

+ + + + + + + + + + + + + + +
仕様書状態備考
{{SpecName('Fetch', '#cors-protocol', 'CORS')}}{{Spec2('Fetch')}}W3C CORS 仕様書を置き換える新しい定義です。
+ +

ブラウザーの互換性

+ +

{{Compat("http.headers.Access-Control-Allow-Origin")}}

+ +

互換性のメモ

+ +

Internet Explorer 8 および 9 は XDomainRequest オブジェクトで CORS を提供していますが、完全な実装は IE 10 で行っています。

+ +

関連情報

+ + -- cgit v1.2.3-54-g00ecf