web-dev-qa-db-ja.com

Access-Control-Allow-Originヘッダーはどのように機能しますか?

どうやら、私はその意味論を完全に誤解しています。私はこのようなことを考えました:

  1. クライアントがhttp:// siteAからJavaScriptコードMyCode.jsをダウンロードします - Origin
  2. MyCode.jsのレスポンスヘッダーには、 Access-Control-Allow-Origin:http:// siteB が含まれています。これは、MyCode.jsがサイトBへのクロスOrigin参照を許可されていることを意味します。
  3. クライアントはMyCode.jsのいくつかの機能を起動します。これは、クロスオリジンのリクエストであっても、http:// siteBにリクエストを送信します。

まあ、私は間違っています。これはまったく機能しません。だから、私は クロスオリジンリソース共有 を読み、 w3c勧告でクロスオリジンリソース共有 - を読み込もうとしました

1つ確かなことがあります - 私はまだこのヘッダーをどのように使用することになっているのか理解していないのです。

サイトAとサイトBの両方を完全に制御できます。このヘッダーを使用して、サイトAからダウンロードしたJavaScriptコードがサイトBのリソースにアクセスできるようにするにはどうすればよいですか。

P.S.

JSONPを利用したくありません。

946
mark

Access-Control-Allow-OriginCORS(Cross-Origin Resource Sharing)ヘッダー です。

サイトAがサイトBからコンテンツを取得しようとすると、サイトBはAccess-Control-Allow-Origin応答ヘッダーを送信して、このページのコンテンツが特定のオリジンからアクセス可能であることをブラウザーに通知できます。 (Originドメイン、およびスキームとポート番号 です。)デフォルトでは、サイトBのページは 他からはアクセスできません起源 ; Access-Control-Allow-Originヘッダーを使用すると、特定の要求元によるクロスオリジンアクセスのドアが開きます。

サイトBがサイトAにアクセスできるようにするリソース/ページごとに、サイトBはそのページに応答ヘッダーを提供する必要があります。

Access-Control-Allow-Origin: http://siteA.com

最新のブラウザは、クロスドメインリクエストを完全にブロックしません。サイトAがサイトBからページを要求すると、ブラウザは実際にネットワークレベルで要求されたページを取得し、応答ヘッダーが許可された要求者ドメインとしてサイトAをリストするかどうかを確認します。サイトAがこのページへのアクセスを許可されていることをサイトBが示していない場合、ブラウザはXMLHttpRequesterrorイベントをトリガーし、リクエストするJavaScriptコードへの応答データを拒否します。

非単純なリクエスト

ネットワークレベルで発生することは、上記で説明したよりもわずかにより複雑になる可能性があります。リクエストが "non-simple"リクエスト の場合、ブラウザは最初にデータなしの「プリフライト」OPTIONSリクエストを送信し、サーバーがリクエストを受け入れることを確認します。次のいずれか(または両方)の場合、要求は単純ではありません。

  • gETまたはPOST(PUT、DELETEなど)以外のHTTP動詞を使用する
  • 非単純なリクエストヘッダーを使用します。唯一の単純なリクエストヘッダーは次のとおりです。
    • Accept
    • Accept-Language
    • Content-Language
    • Content-Type(これは、その値がapplication/x-www-form-urlencodedmultipart/form-data、またはtext/plainである場合にのみ簡単です)

サーバーがOPTIONSプリフライトに、非単純な動詞や非単純なヘッダーに一致する適切な応答ヘッダー(非単純な動詞の場合はAccess-Control-Allow-Headers、非単純な動詞の場合はAccess-Control-Allow-Methods)で応答する場合、その後、ブラウザは実際のリクエストを送信します。

サイトAが/somePageに対してPUTリクエストを送信し、Content-Typeの非シンプルなapplication/json値を使用すると、ブラウザは最初にプリフライトリクエストを送信します。

OPTIONS /somePage HTTP/1.1
Origin: http://siteA.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type

Access-Control-Request-MethodAccess-Control-Request-Headersはブラウザによって自動的に追加されることに注意してください。それらを追加する必要はありません。このOPTIONSプリフライトは、成功した応答ヘッダーを取得します。

Access-Control-Allow-Origin: http://siteA.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type

(プリフライトが実行された後)実際のリクエストを送信するときの動作は、単純なリクエストの処理方法と同じです。言い換えれば、プリフライトが成功した非単純なリクエストは、単純なリクエストと同様に扱われます(つまり、サーバーは実際の応答のためにAccess-Control-Allow-Originを再度送信する必要があります)。

ブラウザは実際のリクエストを送信します:

PUT /somePage HTTP/1.1
Origin: http://siteA.com
Content-Type: application/json

{ "myRequestContent": "JSON is so great" }

そして、サーバーは、単純なリクエストの場合と同様に、Access-Control-Allow-Originを送り返します。

Access-Control-Allow-Origin: http://siteA.com

非単純なリクエストの詳細については、 CORSでのXMLHttpRequestの理解 を参照してください。

1286
apsillers

クロスオリジンリクエストの共有 - CORS(AKA Cross-Domain AJAX request)は、Same-Origin-Policyによると、ブラウザがセキュリティサンドボックス内のクライアントJavaScriptを制限する、通常はJS別のドメインのリモートサーバーと直接通信することはできません。過去に開発者は、クロスドメインリソース要求を達成するための多くのトリッキーな方法を作成しました。最も一般的な方法は次のとおりです。

  1. リモートと通信するための "プロキシ"としてFlash/Silverlightまたはサーバー側を使用してください。 
  2. JSON with Padding( _ jsonp _ )。 
  3. リモートサーバーをiframeに埋め込み、fragmentまたはwindow.nameを介して通信します。 ここ を参照してください。

例えば、開発者が単純に "評価"した場合JSONPでセキュリティホールが発生する可能性があります。#3上記の問題は解決しますが、どちらのドメインも厳密な契約を構築する必要があります。私見では:)

W3Cは、この問題を解決するための安全で柔軟で推奨される標準的な方法を提供するための標準ソリューションとしてCross-Origin Resource Sharing(CORS)を導入しました。 

メカニズム

大まかに言うと、CORSはドメインAからのクライアントAJAX呼び出しとドメインBでホストされているページの間の契約であると単純に見なすことができます。

DomainA AJAXリクエストヘッダー

Host DomainB.com
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/json
Accept-Language en-us;
Accept-Encoding gzip, deflate
Keep-Alive 115
Origin http://DomainA.com 

DomainBレスポンスヘッダー

Cache-Control private
Content-Type application/json; charset=utf-8
Access-Control-Allow-Origin DomainA.com
Content-Length 87
Proxy-Connection Keep-Alive
Connection Keep-Alive

私が上でマークした青い部分はカーネルファクトで、 "Origin"リクエストヘッダはクロスオリジンリクエストまたはプリフライトリクエストがどこから来たのかを示し、 "Access-Control-Allow-Origin"レスポンスヘッダはこのページがリモートリクエストを許可することを示しますDomainA(値が*の場合、任意のドメインからのリモート要求が許可されます)。

先に述べたように、W3は実際にはCross-Origin HTTPリクエストを送信する前に " プリフライトリクエスト "を実装することをブラウザに推奨しました。要するにそれはHTTPのOPTIONSリクエストです:

OPTIONS DomainB.com/foo.aspx HTTP/1.1

Foo.aspxがOPTIONS HTTP動詞をサポートしている場合、以下のような応答が返される可能性があります。

HTTP/1.1 200 OK
Date: Wed, 01 Mar 2011 15:38:19 GMT
Access-Control-Allow-Origin: http://DomainA.com
Access-Control-Allow-Methods: POST, GET, OPTIONS, HEAD
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Max-Age: 1728000
Connection: Keep-Alive
Content-Type: application/json

応答に "Access-Control-Allow-Origin"が含まれ、その値が "*"である場合、またはCORS要求を送信したドメインが含まれる場合にのみ、この必須条件を満たすことでブラウザは実際のクロスドメイン要求を送信し、結果をキャッシュします。 " プリフライト結果キャッシュ "に。

3年前にCORSについてブログを書きました: AJAX Cross-Origin HTTP request

107
Wayne Ye

質問は答えるには少し古すぎるが、私はこの質問への将来の参照のためにこれを投稿している。

これ / Mozilla Developer Networkの記事によると、

リソースは、最初のリソース自体がサービスを提供しているドメインとは異なるドメインまたはポートからリソースを要求すると、 クロスオリジンHTTP要求 を発行します。

enter image description here

http://domain-a.comから提供される HTMLページ は、<img>に対してhttp://domain-b.com/image.jpg src要求を出します。
今日のWeb上の多くのページは、 CSSスタイルシート images 、および scripts のようなリソースを別々のドメインからロードしています。

同一オリジンポリシー

セキュリティ上の理由から、ブラウザは クロスオリジンHTTP requests スクリプト内から開始される を制限します。
たとえば、XMLHttpRequestname__およびFetchname__は、 same-Originポリシー に従います。
したがって、XMLHttpRequestname__またはFetchname__を使用するWebアプリケーションは、 HTTP要求 から 独自のドメイン のみを作成できます。

クロスオリジンリソース共有(CORS)

Webアプリケーションを改善するために、開発者はブラウザベンダーにクロスドメインリクエストを許可するように依頼しました。

クロスオリジンリソース共有(CORS) メカニズムは、安全なクロスドメインデータ転送を可能にするWebサーバー クロスドメインアクセス制御 を提供します。
最近のブラウザは、クロスオリジンHTTPリクエストのリスクを軽減するために、XMLHttpRequestname__やFetchname__のように APIコンテナ - で _ cors _ を使用します。

CORSのしくみ(Access-Control-Allow-Originヘッダー)

ウィキペディア

CORS規格では、ブラウザとサーバーにアクセス権がある場合にのみリモートURLを要求する方法を提供する新しいHTTPヘッダーについて説明しています。

いくらかの検証と認可はサーバによって実行されることができますが、 これらのヘッダをサポートし、それらが課す制限を守ることは一般的にブラウザの責任です

  1. ブラウザはOrigin HTTPヘッダを付けてOPTIONSname__リクエストを送信します。 

    このヘッダーの値は、親ページを提供していたドメインです。 http://www.example.comのページがservice.example.com内のユーザーのデータにアクセスしようとすると、次のリクエストヘッダーがservice.example.comに送信されます。

    原産地: http://www.example.com

  2. service.example.comのサーバーは次のように応答します。

    • どのOriginサイトが許可されているかを示す応答内のAccess-Control-Allow-Origin(ACAO)ヘッダー。
      例えば: 

      Access-Control-Allow-Origin: http://www.example.com

    • サーバーがクロスオリジン要求を許可しない場合のエラーページ

    • すべてのドメインを許可するワイルドカード付きのAccess-Control-Allow-Origin(ACAO)ヘッダー

      Access-Control-Allow-Origin: *

42
Trix

CORSについて考え始めると、質問で説明したように、ヘッダーをホストしているサイトに関する私の直感は間違っています。私にとっては、同じOriginポリシーの目的を考えるのに役立ちます。

同じOriginポリシーの目的は、siteA.com上の悪意のあるJavaScriptから、siteB.comのみと共有することを選択した個人情報にアクセスすることからユーザーを保護することです。同じOriginポリシーがなければ、siteA.comの作成者が作成したJavaScriptは、siteB.comの認証Cookieを使用して、ブラウザーからsiteB.comへのリクエストを行うことができます。このようにして、siteA.comは、siteB.comと共有する秘密情報を盗む可能性があります。

場合によっては、CORSの出番であるクロスドメインで作業する必要があります。CORSは、Access-Control-Allow-Originヘッダーを使用して、JavaScriptを実行することが信頼されている他のドメイン(domainB.com)をリストし、domainA.comの同じOriginポリシーを緩和しますdomainA.comと対話できます。

CORSヘッダーを提供するドメインを理解するには、これを考慮してください。悪意のあるサイトにアクセスします。このサイトには、mybank.comにクロスドメインリクエストを送信しようとするJavaScriptが含まれています。これは、同じOriginポリシーを緩和するCORSヘッダーを設定するかどうかを決めるのは、malicious.comではなくmybank.comである必要があります。これにより、malicious.comのJavaScriptがそれと対話できます。 malicous.comが独自のCORSヘッダーを設定して、mybank.comへの独自のJavaScriptアクセスを許可できる場合、同じOriginポリシーが完全に無効になります。

私の悪い直観の理由は、サイトを開発するときに私が持っている視点だと思います。 myサイト、すべてmy JavaScriptであるため、悪意のあることは何もせず、他のどのサイトを指定するかはmemy JavaScriptは対話できます。実際にどのotherサイトがJavaScriptと私のサイトとのやり取りを試みているのかを考える必要がありますが、それらを許可するためにCORSを使用する必要がありますか?

17
Dom

React および Axios を使用して、プロキシリンクをURLに追加し、次に示すようにヘッダーを追加します

https://cors-anywhere.herokuapp.com/ + Your API URL

プロキシリンクを追加するだけで動作しますが、それはまたアクセスなしのためのエラーをスローすることができます。したがって、以下に示すようにヘッダーを追加することをお勧めします。

axios.get(`https://cors-anywhere.herokuapp.com/[YOUR_API_URL]`,{headers: {'Access-Control-Allow-Origin': '*'}})
      .then(response => console.log(response:data);
  }
8
Dhaval Jardosh

ブラウザが要求をブロックするクロスドメインアプリケーションをテストするだけの場合は、ブラウザを安全でないモードで開き、コードを変更せずにコードを安全にすることなくアプリケーションをテストできます。 OSあなたは端末ラインからこれを行うことができます:

open -a Google\ Chrome --args --disable-web-security --user-data-dir
8

1.クライアントが http:// siteA - >からJavaScriptコードMyCode.jsをダウンロードします。

ダウンロードを実行するコード - あなたのhtmlスクリプトタグ、またはjavascriptからのxhrなど - が由来します、例えば、 http:// siteZ です。また、ブラウザがMyCode.jsを要求すると、 "Origin: http:// siteZ "というOrigin:ヘッダーが送信されます。これは、siteAとsiteZ!= siteAに要求していることがわかるためです。 (あなたはこれを止めることも妨害することもできません。)

2. MyCode.jsのレスポンスヘッダにはAccess-Control-Allow-Origin: http:// siteB が含まれています。サイトB

いいえ。つまり、siteBだけがこのリクエストを実行できるということです。そのため、siteZからMyCode.jsを要求しても代わりにエラーが発生し、ブラウザからは通常何も表示されません。しかし、サーバーにA-C-A-O:siteZを返させると、MyCode.jsが返されます。あるいは '*'を送れば、それはうまくいくでしょう。それはみんなを入れてくれるでしょう。あるいはサーバが常にOrigin:ヘッダから文字列を送るのであれば...しかしセキュリティのために...もしあなたがハッカーを恐れているならあなたのサーバーはこれらの要求をすることが許されているショートリスト上の起源のみを許すべきです。

それから、MyCode.jsはsiteAから来ます。 siteBにリクエストを送信すると、それらはすべてクロスOriginであり、ブラウザはOrigin:siteAを送信し、siteBはsiteAを取得し、許可されたリクエスタの短いリストにあることを認識し、A-C-A-O:siteAを返信します。そうして初めて、ブラウザはあなたのスクリプトにそれらのリクエストの結果を取得させます。

6
OsamaBinLogin

私はエクスプレス4とノード7.4と角度で動作し、私はこれを助ける同じ問題を抱えていた:
a)サーバー側:ファイルapp.jsで、私は以下のようにすべての応答にヘッダーを付けます。

app.use(function(req, res, next) {  
      res.header('Access-Control-Allow-Origin', req.headers.Origin);
      res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
      next();
 });  

これはすべてのルータの前になければなりません
このヘッダーがたくさん追加されています。

res.header("Access-Control-Allow-Headers","*");
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');

しかし、私はそれを必要としない、
b)クライアント側:ajaxを送信するには、 "withCredentials:true"を追加します。

$http({
     method: 'POST',
     url: 'url, 
     withCredentials: true,
     data : {}
   }).then(function(response){
        // code  
   }, function (response) {
         // code 
   });

がんばろう。

6
izik f

PHPを使用している場合は、phpファイルのBeanに次のコードを追加してください。

localhostを使用している場合は、これを試してください。

header("Access-Control-Allow-Origin: *");

サーバーなどの外部ドメインを使用している場合は、これを試してください。

header("Access-Control-Allow-Origin: http://www.website.com");
3
Melvin Guerrero

クロスオリジン共有の場合は、ヘッダを設定してください:'Access-Control-Allow-Origin':'*';

Php:header('Access-Control-Allow-Origin':'*');

ノード:app.use('Access-Control-Allow-Origin':'*');

これにより、異なるドメインのコンテンツを共有できます。

2
suryadev

Pythonでは、私は Flask-CORSライブラリ を使ってきました。それはCORSを扱うことを超簡単でそして痛みのないものにします。以下のライブラリのドキュメントからコードを追加しました。 

インストール:

$ pip install -U flask-cors

すべてのルート上のすべてのドメインに対してCORSを許可する簡単な例:

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def helloWorld():
  return "Hello, cross-Origin-world!"

より具体的な例については、資料を参照してください。私が構築しているイオンアプリケーションでCORS問題を回避するために上記の簡単な例を使用しました。

2
agaidis

Access-Control-Allow-Origin応答ヘッダーは、応答を特定のOriginからの要求コードと共有できるかどうかを示します。

Header type Response       header
Forbidden header name      no

任意のOriginからのコードにリソースへのアクセスを許可するようブラウザに指示する応答には、次のものが含まれます。

Access-Control-Allow-Origin: *

詳細については、 here ....にアクセスしてください。

0
Alireza

Web.configファイルに次のコードを貼り付けるだけです。

次のコードを<system.webServer>タグの下に貼り付ける必要があります

    <httpProtocol>  
    <customHeaders>  
     <add name="Access-Control-Allow-Origin" value="*" />  
     <add name="Access-Control-Allow-Headers" value="Content-Type" />  
     <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />  
    </customHeaders>  
  </httpProtocol>  
0
Juboraj Sarker