これにより、ブラウザはXMLHttpRequestリクエストをクロスオリジンサーバーに発行でき、AJAXは同じ原点でのみ使用できるという制限を克服できます。
この記事では、CORの内部メカニズムを詳細に紹介します。
(写真の説明:UAE、アルアインのオアシスパークで撮影)
1。はじめに
CORSには、ブラウザとサーバーの両方のサポートが必要です。現在、すべてのブラウザはこの機能をサポートしており、IEブラウザはIE10よりも低くすることはできません。
CORS通信プロセス全体がブラウザによって自動的に完了し、ユーザーの参加は必要ありません。開発者にとって、CORS通信は同じオリジンAJAX通信と変わりません。コードはまったく同じです。ブラウザがAjaxがクロスオリジンを要求することを発見すると、自動的に追加のヘッダー情報が追加され、追加のリクエストがある場合がありますが、ユーザーはそれを感じません。
したがって、CORS通信を実装するための鍵はサーバーです。サーバーがCORSインターフェイスを実装する限り、クロスオリジン通信を実行できます。
2つのリクエスト
ブラウザは、CORSリクエストを2つのカテゴリに分割します:シンプルな要求とそれほどsimpleではないリクエスト。
次の2つの主要な条件が同時に満たされている限り、それは簡単な要求です。
(1)リクエスト方法は、次の3つの方法のいずれかです。
headgetPost
(2)HTTPのヘッダー情報は、次のフィールドを超えていません。
AcceptAccept-Languagecocontent-languagelast text/plain event-idcontent-type:3つの値のみに制限されてmultipart/form-dataますapplication/x-www-form-urlencoded
上記の2つの条件を同時に満たしていない人は誰でも、不可解な要求です。
ブラウザのこれら2つのリクエストの処理は異なります。
3.簡単な要求3.1基本プロセス
簡単な要求のために、ブラウザはCORSリクエストを直接発行します。具体的には、ヘッダー情報にOriginフィールドを追加します。
以下は例です。ブラウザは、このクロスオリジンAJAX要求が簡単な要求であることを発見し、ヘッダー情報にOriginフィールドを自動的に追加しました。
GET /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
上記のヘッダー情報では、 Originフィールドを使用して、リクエストのソース(プロトコル +ドメイン名 +ポート)を示します。この値に基づいて、サーバーはリクエストに同意するかどうかを決定します。
Originで指定されたソースが許可範囲内にない場合、サーバーは通常のHTTP応答を返します。ブラウザは、この応答のヘッダー情報にAccess-Control-Allow-Originフィールドが含まれていないことを発見したため(詳細については以下を参照)、エラーが発生したため、エラーがスローされ、 XMLHttpRequestのonerrorコールバック関数によってキャプチャされました。 HTTP応答のステータスコードが200になる可能性があるため、このエラーはステータスコードで識別できないことに注意してください。
Originで指定されたドメイン名が許可範囲内である場合、サーバーによって返される応答にはいくつかの追加のヘッダーフィールドがあります。
Access-Control-Allow-Origin: http://api.bob.comAccess-Control-Allow-Credentials: trueAccess-Control-Expose-Headers: FooBarContent-Type: text/html; charset=utf-8
上記のヘッダー情報の中には、CORSリクエストに関連する3つのフィールドがあり、すべてAccess-Control-から始まります。
(1)アクセス制御 - アロウオリジン
この項目は必須です。その値は、要求時のOriginフィールドの値またはa *いずれかであり、ドメイン名のリクエストが受け入れられていることを示しています。
(2)アクセスコントロール - アロウ - クレジンシャル
このフィールドはオプションです。その値は、Cookieの送信を許可するかどうかを示すブール値です。デフォルトでは、CookieはCORSリクエストに含まれていません。 trueに設定します。つまり、サーバーが明示的に許可することを意味します。 Cookieをリクエストに含めて一緒にサーバーに送信できます。この値はtrueにのみ設定できます。サーバーがブラウザによってCookieを送信しない場合は、フィールドを削除します。
(3)アクセスコントロール露出担当者
このフィールドはオプションです。 CORSが要求する場合、 XMLHttpRequestオブジェクトのgetResponseHeader()メソッドは、 Cache-Control 、 Content-Language 、 Content-Type 、 Expires 、 Last-Modified 、 Pragma 6つの基本フィールドのみを取得できます。他のフィールドを取得したい場合は、 Access-Control-Expose-Headersでそれらを指定する必要があります。上記の例は、 getResponseHeader('FooBar') FooBarフィールドの値を返すことができることを指定しています。
3.2 withcredentials属性
上記のように、CORSリクエストは、デフォルトでCookieとHTTP認証情報を送信しません。一方で、サーバーにCookieを送信する場合は、サーバーが同意してAccess-Control-Allow-Credentialsフィールドを指定する必要があります。
Access-Control-Allow-Credentials: true一方、開発者は、AJAXリクエストでwithCredentialsプロパティを開く必要があります。
var xhr = new XMLHttpRequest();xhr.withCredentials = true;それ以外の場合、サーバーがCookieの送信に同意しても、ブラウザは送信しません。あるいは、サーバーはCookieを設定する必要があり、ブラウザはそれを処理しません。
ただし、 withCredentials設定が省略されている場合、一部のブラウザはまだCookieを送信します。現時点では、 withCredentials明示的に閉じることができます。
xhr.withCredentials = false; Cookieを送信する場合は、 Access-Control-Allow-Originをアスタリスクとして設定することはできず、要求されたWebページと一致する明示的なドメイン名を指定する必要があることに注意してください。同時に、Cookieは依然として同じオリジンポリシーに従います。サーバードメイン名で設定されたCookieのみがアップロードされます。他のドメイン名からのCookieはアップロードされず、 document.cookieオリジナル(オリジナル)WebページコードのCookiesは、サーバードメイン名の下でCookieを読み取ることができません。
4。非simpleリクエスト4.1飛行前リクエスト
非シンプルリクエストは、リクエストメソッドがPUTまたはDELETE 、 Content-Typeフィールドタイプがapplication/jsonなど、サーバーに特別な要件がある要求です。
単純なリクエストではないCORSリクエストは、公式通信の前にHTTPクエリリクエストを追加します。これは「プレイライト」リクエストと呼ばれます。
ブラウザは、最初にサーバーに、現在のWebページが配置されているドメイン名がサーバーのライセンスリストにあるかどうか、どのHTTP動詞とヘッダーフィールドを使用できるかを尋ねます。肯定的な返信が受信された場合にのみ、ブラウザは正式なXMLHttpRequestリクエストを発行します。そうしないと、エラーが報告されます。
以下は、ブラウザJavaScriptスクリプトです。
var url = 'http://api.alice.com/cors';var xhr = new XMLHttpRequest();xhr.open('PUT', url, true);xhr.setRequestHeader('X-Custom-Header', 'value');xhr.send();
上記のコードでは、HTTPリクエストメソッドがPUT 、カスタムヘッダー情報X-Custom-Headerが送信されます。
ブラウザは、これが非シンプルなリクエストであることを発見したため、「事前に飛行する」リクエストを自動的に発行し、これを要求できることをサーバーに確認する必要があります。以下は、この「プリフライト」リクエストのHTTPヘッダー情報です。
OPTIONS /cors HTTP/1.1Origin: http://api.bob.comAccess-Control-Request-Method: PUTAccess-Control-Request-Headers: X-Custom-HeaderHost: api.alice.comAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0... 「プレイライト」要求で使用される要求方法はOPTIONSであり、このリクエストが問い合わせに使用されることを示します。ヘッダー情報では、キーフィールドはOriginであり、リクエストがどのソースから来るかを示します。
Originフィールドに加えて、「Preflight」要求のヘッダー情報には2つの特別なフィールドが含まれています。
(1)Access-Control-Request-Method
このフィールドは、ブラウザのCORSリクエストに使用されるHTTPメソッドをリストするために必要です。上記の例がPUT 。
(2)アクセスコントロール - レクエストヘッダー
このフィールドは、ブラウザCORSリクエストが送信する追加のヘッダー情報フィールドを指定するコンマ区切り文字列です。上記の例はX-Custom-Headerです。
4.2飛行前のリクエストへの応答
サーバーが「プリフライト」リクエストを受信した後、 Origin 、 Access-Control-Request-Method 、 Access-Control-Request-Headersフィールドを確認した後、オリジンクロスリクエストが許可されていることを確認し、応答できます。
HTTP/1.1 200 OKDate: Mon, 01 Dec 2008 01:15:39 GMTServer: Apache/2.0.61 (Unix)Access-Control-Allow-Origin: http://api.bob.comAccess-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Headers: X-Custom-HeaderContent-Type: text/html; charset=utf-8Content-Encoding: gzipContent-Length: 0Keep-Alive: timeout=2, max=100Connection: Keep-AliveContent-Type: text/plain
上記のHTTP応答では、キーはAccess-Control-Allow-Originフィールドです。つまり、 http://api.bob.comデータをリクエストできます。このフィールドは、クロスオリジンリクエストに同意するアスタリスクに設定することもできます。
Access-Control-Allow-Origin: *
ブラウザが「プレイライト」リクエストを無効にすると、通常のHTTP応答が返されますが、CORS関連のヘッダーフィールドはありません。この時点で、ブラウザはサーバーがプリライトリクエストに同意しないことを決定するため、 XMLHttpRequestオブジェクトのonerrorコールバック関数によってエラーがトリガーおよびキャプチャされます。コンソールには、次のエラーメッセージが印刷されます。
XMLHttpRequest cannot load http://api.alice.com.Origin http://api.bob.com is not allowed by Access-Control-Allow-Origin.
サーバーが応答する他のCORS関連フィールドは次のとおりです。
Access-Control-Allow-Methods: GET, POST, PUTAccess-Control-Allow-Headers: X-Custom-HeaderAccess-Control-Allow-Credentials: trueAccess-Control-Max-Age: 1728000(1)アクセスコントロール - アロウメソッド
このフィールドが必要であり、その値は、サーバーがサポートするすべてのクロスドメイン要求方法を示すコンマ区切り文字列です。ブラウザが要求したものだけでなく、サポートされているすべてのメソッドが返されることに注意してください。これは、複数の「プリフライト」リクエストを回避するためです。
(2)アクセス制御 - アロウヘッド
ブラウザリクエストにAccess-Control-Request-Headersフィールドが含まれている場合、 Access-Control-Allow-Headersフィールドが必要です。また、サーバーでサポートされているすべてのヘッダーフィールドが「プリフライト」でブラウザが要求するフィールドに限定されないことを示すコンマ区切り文字列でもあります。
(3)アクセスコントロール - アロウ - クレジンシャル
このフィールドは、単純な方法で要求されたときと同じ意味を持っています。
(4)アクセスコントロール-Max-age
このフィールドはオプションであり、数秒でこのプリライトリクエストの有効期間を指定するために使用されます。上記の結果では、有効期間は20日間(1728,000秒)です。つまり、応答は1728,000秒(つまり20日間)にキャッシュされます。この期間中、他のプリフライトリクエストは必要ありません。
4.3ブラウザからの通常のリクエストと応答
サーバーが「プレイライト」要求を渡すと、ブラウザの通常のCORSリクエストが簡単な要求と同じになるたびに、 Origin Header情報フィールドがあります。サーバーの応答Access-Control-Allow-Originヘッダーフィールドもあります。
以下は、「プリライト」リクエスト後のブラウザの通常のCORSリクエストです。
PUT /cors HTTP/1.1Origin: http://api.bob.comHost: api.alice.comX-Custom-Header: valueAccept-Language: en-USConnection: keep-aliveUser-Agent: Mozilla/5.0...
上記のヘッダー情報のOriginフィールドは、ブラウザによって自動的に追加されます。
以下は、サーバーからの通常の応答です。
Access-Control-Allow-Origin: http://api.bob.comContent-Type: text/html; charset=utf-8
上記のヘッダー情報では、各応答にAccess-Control-Allow-Originフィールドを含める必要があります。
5。JSONPとの比較
CORSはJSONPと同じ目的で使用されますが、JSONPよりも強力です。
JSONPはGETリクエストのみをサポートし、CORSはあらゆる種類のHTTPリクエストをサポートします。 JSONPの利点は、昔ながらのブラウザをサポートし、CORSをサポートしていないWebサイトからデータをリクエストできることです。
(以上)