Skip to content
学習する 測定する ブログ Case studies 概要
このページ内
  • リソースリクエストはWeb上でどのように機能しますか?
    • 本文
  • CORSはどのように機能しますか?
    • ステップ1:クライアント (ブラウザー) リクエスト
    • ステップ2:サーバーレスポンス
    • ステップ3:ブラウザがレスポンスを受信する
  • CORSの実例
  • CORSとクレデンシャルを共有する
    • リクエスト
    • レスポンス
  • 複雑なHTTP呼び出しのプリフライトリクエスト

クロスオリジンリソースシェアリング(CORS)

クロスオリジンリソースを安全に共有する

Nov 5, 2018
Available in: Español, 한국어, Português, Русский, 中文, English
Appears in: 安全とセキュリティ
Mariko Kosaka
Mariko Kosaka
TwitterGitHubGlitchHomepage
このページ内
  • リソースリクエストはWeb上でどのように機能しますか?
    • 本文
  • CORSはどのように機能しますか?
    • ステップ1:クライアント (ブラウザー) リクエスト
    • ステップ2:サーバーレスポンス
    • ステップ3:ブラウザがレスポンスを受信する
  • CORSの実例
  • CORSとクレデンシャルを共有する
    • リクエスト
    • レスポンス
  • 複雑なHTTP呼び出しのプリフライトリクエスト

ブラウザの same-origin ポリシーは、別のオリジンからのリソースの読み取りをブロックします。このメカニズムは、悪意のあるサイトが別のサイトのデータを読み取るのを防ぎますが、正当な使用も防がれてしまいます。他の国から気象データを取得したい場合はどうすればいいでしょうか?

最新のWebアプリケーションでは、アプリケーションが別のオリジンからリソースを取得したがることがよくあります。たとえば、別のドメインからJSONデータを取得したり、別のサイトの画像を<canvas>要素に読み込んだりすることが必要な場合があります。

つまり、誰もが読み取れるばずの公開リソースまでもが、same-origin ポリシーによってブロックされてしまうのです。開発者はJSONPなどの回避策を使用しましたが、**Cross-Origin Resource Sharing (クロスオリジンリソースシェアリング (CORS)) を使用すれば、**これを標準的な方法で修正できます。

CORSを有効にすると、サーバーはブラウザに別のオリジンの使用が許可されていることを通知できます。

リソースリクエストはWeb上でどのように機能しますか? #

request and response
図:図示されたクライアントリクエストとサーバーレスポンス

ブラウザとサーバーは、Hypertext Transfer Protocol (ハイパーテキスト転送プロトコル) (HTTP) を使用することにより、ネットワーク経由でデータのやり取りを行えます。 HTTPは、リソースを取得するために必要な情報など、リクエスターとレスポンダー間の通信ルールを定義します。

HTTPヘッダーは、クライアントとサーバーの間で行うメッセージ交換の種類をネゴシエートするために使用されるほか、アクセスを決定するためにも使用されます。ブラウザのリクエストとサーバーのレスポンスメッセージはどちらも、ヘッダーと本文の2つの部分に分けられます。

ヘッダー #

メッセージの種類やエンコーディングなど、メッセージに関する情報。ヘッダーには、キーと値のペアとして表されるさまざまな情報を含めることができます。リクエストヘッダーとレスポンスヘッダーには異なる情報が含まれています。

ヘッダーにコメントを含めることはできないのでご注意ください。

リクエストヘッダーの例

Accept: text/html
Cookie: Version=1

上記は、「HTML を返してください。Cookieはこちらです」という内容のリクエストです。

レスポンスヘッダーの例

Content-Encoding: gzip
Cache-Control: no-store

上記は、「データはgzipでエンコードされています。これをキャッシュしないでください」という内容のレスポンスです。

本文 #

これは、メッセージそのものです。プレーンテキスト、画像バイナリ、JSON、HTMLなどが該当します。

CORSはどのように機能しますか? #

same-originポリシーはクロスオリジンリクエストをブロックする指示をブラウザに出すということを覚えておきましょう。別のオリジンからパブリックリソースを取得する場合、リソースを提供するサーバーはブラウザに「リクエストの送信元であるこのオリジンは私のリソースにアクセスできます」と通知を出す必要があります。ブラウザはそれを記憶し、オリジン間でのリソースの共有を可能にします。

ステップ1:クライアント (ブラウザー) リクエスト #

ブラウザは、クロスオリジンリクエストを出す際に、現在のオリジン (スキーム、ホスト、ポート) 付きの Origin ヘッダーを追加します。

ステップ2:サーバーレスポンス #

サーバー側では、このヘッダーを見てアクセスを許可する場合、レスポンスに Access-Control-Allow-Originを追加してリクエスト元を指定する必要があります (もしくは *を使用してあらゆるオリジンを許可します)。

ステップ3:ブラウザがレスポンスを受信する #

ブラウザは、レスポンスに適切なAccess-Control-Allow-Originヘッダーが付けられているのを見ると、レスポンスデータがクライアントサイトと共有されることを許可します。

CORSの実例 #

Expressを使用する小さなWebサーバーがあります。

最初のエンドポイント (8行目) にはレスポンスヘッダーが設定されておらず、レスポンスとしてファイルを送信します。

  • Press `Control+Shift+J` (or `Command+Option+J` on Mac) to open DevTools. - Press `Control+Shift+J` (or `Command+Option+J` on Mac) to open DevTools.

  • Click the Console tab.

  • 次のコマンドを試してください。

fetch('https://cors-demo.glitch.me/', {mode:'cors'})

次のようなエラーが表示されます。

request has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header
is present on the requested resource.

2番目のエンドポイント (13行目) は、応答として同じファイルを送信しますが、ヘッダーにAccess-Control-Allow-Origin: *を追加します。コンソールから、以下のコードを試してみてください

fetch('https://cors-demo.glitch.me/allow-cors', {mode:'cors'})

今回は、リクエストがブロックされないはずです。

CORSとクレデンシャルを共有する #

プライバシー上の理由から、CORSは通常、「匿名リクエスト」(リクエストがリクエスターを識別しないリクエスト) に使用されます。CORS (送信者を識別できる) を使用するときにCookieを送信する場合は、リクエストとレスポンスにヘッダーを追加する必要があります。

リクエスト #

以下のように、credentials: 'include'をフェッチオプションに追加します。これにより、クッキーがリクエストに追加されます。

fetch('https://example.com', {
mode: 'cors',
credentials: 'include'
})

レスポンス #

Access-Control-Allow-Originは特定のオリジンに設定する必要があり、(*を使ったワイルドカードはなし)。また Access-Control-Allow-Credentialsは、をtrueに設定する必要があります。

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true

複雑なHTTP呼び出しのプリフライトリクエスト #

Webアプリで複雑なHTTPリクエストが必要な場合、ブラウザは**プリフライトリクエスト**をリクエストチェーンの先頭に追加します。

CORS仕様では、複雑なリクエストは以下のように定義されています。

  • GET、POST、またはHEAD以外のメソッドを使用するリクエスト
  • Accept 、 Accept-LanguageまたはContent-Language以外のヘッダーを含むリクエスト
  • application/x-www-form-urlencoded 、 multipart/form-data 、またはtext/plain以外のContent-Typeヘッダーを持つリクエスト

ブラウザは、必要に応じてプリフライトリクエストを作成します。これは、以下のようなOPTIONSリクエストであり、実際のリクエストメッセージの前に送信されます。

OPTIONS /data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: DELETE

サーバー側では、アプリケーションは、アプリケーションがこのオリジンから受け入れるメソッドに関する情報をもってプリフライトリクエストに応答する必要があります。

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, DELETE, HEAD, OPTIONS

サーバーのレスポンスには、Access-Control-Max-Ageヘッダーを含めて、プリフライトの結果をキャッシュする期間 (秒単位) を指定することもできるため、クライアントは複雑なリクエストを送信するたびにプリフライトリクエストを行う必要がありません。

セキュリティ
最終更新: Nov 5, 2018 — 記事を改善する
Return to all articles
共有する
サブスクライブする

Contribute

  • バグを報告する
  • ソースを表示する

関連性のあるコンテンツ

  • developer.chrome.com
  • Chrome のアップデート
  • Web Fundamentals
  • ケーススタディ
  • ポッドキャスト
  • ショー

接続する

  • Twitter
  • YouTube
  • Google Developers
  • Chrome
  • Firebase
  • Google Cloud Platform
  • すべての製品
  • 利用規約とプライバシーポリシー
  • コミュニティガイドライン

Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License. For details, see the Google Developers Site Policies.