Express.jsサーバーのインスタンスを開始するGruntプロセスがあります。これは、Chrome(最新バージョン)の開発者コンソールのエラーログに次のような空白のページが表示され始めたときまで、まったく問題なく機能していました。
XMLHttpRequestをロードできません https://www.example.com/ 要求されたリソースに「Access-Control-Allow-Origin」ヘッダーがありません。したがって、オリジン ' http:// localhost:43 'はアクセスを許可されていません。
ページへのアクセスを妨げるものは何ですか?
これは Same Origin Policy です。これは、ブラウザによって実装されるセキュリティ機能です。
あなたの特定のケースは、XMLHttpRequestにどのように実装されているかを示しています(フェッチを使用する場合は同じ結果が得られます)が、他のものにも適用されます(<canvas>
に読み込まれた画像や<iframe>
に読み込まれたドキュメントなど)、実装がわずかに異なるだけです。
(奇妙なことに、CSSフォントにも適用されますが、ファウンドリがDRMを主張しており、Same Origin Policyが通常カバーするセキュリティの問題ではないためです)。
SOPの必要性を実証する標準シナリオは、 文字 で実証できます。
https://www.[website].com/
)http://localhost:4300
)アリスはボブのサイトにログインし、そこにいくつかの機密データがあります。おそらく、会社のイントラネット(LAN上のブラウザーのみがアクセス可能)、または彼女のオンラインバンキング(ユーザー名とパスワードを入力した後に取得するCookieでのみアクセス可能)です。
アリスは、アリスのブラウザがボブのウェブサイトにHTTPリクエストを行う原因となるJavaScriptを備えたマロリーのウェブサイトにアクセスします(彼女のIPアドレスからクッキーなどを使用)。これは、XMLHttpRequest
を使用してresponseText
を読み取るのと同じくらい簡単です。
ブラウザのSame Origin Policyは、BobのWebサイト(BobとAliceがMalloryにアクセスさせたくない)から返されたデータをJavaScriptが読み取れないようにします。 (たとえば、画像のコンテンツがJavaScript(またはMallory)に公開されていないため、<img>
要素を使用して画像を表示できることに注意してください...キャンバスをミックスにスローしない限り、 willは、同一生成元違反エラーを生成します)。
任意のURLについて、SOPが不要になる可能性があります。この場合の一般的なシナリオは次のとおりです。
…しかし、ブラウザは上記のいずれかが真であるかどうかを知る方法がないため、信頼は自動的ではなく、SOPが適用されます。ブラウザが別のWebサイトに与えられたデータをブラウザが与える前に、許可を明示的に付与する必要があります。
ブラウザ拡張機能、ブラウザ開発者ツールの[ネットワーク]タブ、およびPostmanなどのアプリケーションはインストール済みソフトウェアです。あるWebサイトから別のWebサイトに属するJavaScriptにデータを渡していないのは、その別のWebサイトにアクセスしたからです。通常、ソフトウェアのインストールにはより意識的な選択が必要です。
リスクと見なされる第三者(Mallory)はありません。
Malloryのサイトがブラウザに第三者からデータを取得させて表示させる多くの状況があります(例えば、画像を表示する<img>
要素を追加することにより)。 MalloryのJavaScriptがそのリソースのデータを読み取ることはできませんが、AliceのブラウザーとBobのサーバーのみがそれを実行できるため、安全です。
エラーメッセージで参照されているAccess-Control-Allow-Origin
ヘッダーは CORS 標準の一部であり、BobはMalloryのサイトに明示的にアクセスを許可して、Aliceのブラウザー経由でデータにアクセスできます。
基本的な実装には次のものが含まれます。
Access-Control-Allow-Origin: *
…Webサイトがデータを読み取ることを許可するため。
Access-Control-Allow-Origin: http://example.com/
…特定のサイトのみがアクセスできるようにし、Origin
requestヘッダーに基づいて動的に生成し、すべてではなく複数のサイトがアクセスできるようにします。
その応答ヘッダーの設定方法の詳細は、BobのHTTPサーバーやサーバー側のプログラミング言語に依存します。 さまざまな一般的な構成のガイドのコレクション が役立つ場合があります。
NB:一部のリクエストは複雑であり、ブラウザがGET/POST/PUT/JSが作成したいリクエストを送信する前にサーバーが応答する必要がある preflight OPTIONSリクエストを送信します。 Access-Control-Allow-Origin
を特定のURLに追加するだけのCORSの実装は、多くの場合、これによって失敗します。
明らかに、CORSを介して許可を与えることは、ボブが次のいずれかの場合にのみ行うことです。
このシナリオであなたもボブである場合、CORSパーミッションヘッダーを追加する方法の詳細は、選択したHTTPサーバーソフトウェアと、サーバー側プログラミングに使用している言語(ある場合)の組み合わせによって異なります。
Malloryはこのヘッダーを追加できません。ボブのサイトから許可を取得する必要があり、(SOPを役に立たなくするほど愚かな)自分に許可を与えることができる。
一部のクロスオリジンリクエストは、 プリフライト です。
これは、(大まかに言えば)次のクロスオリジンリクエストを行おうとしたときに発生します。
enctype
で使用できないカスタムヘッダーまたはContent-Typeがあります)。これらの場合、この回答の残りはまだ適用されますが、サーバーがプリフライトリクエスト(OPTIONS
になる)をリッスンできることを確認する必要もあります(GET
、POST
、または送信しようとしていたもの)ではなく、適切なAccess-Control-Allow-Origin
ヘッダーで応答するだけでなく、特定のHTTPメソッドまたはヘッダーを許可するAccess-Control-Allow-Methods
およびAccess-Control-Allow-Headers
も応答します。
Ajaxリクエストを作成するときに人がミスをすることもあれば、プリフライトが必要になることもあります。 APIがクロスオリジンリクエストを許可するように設計されているが、プリフライトを必要とするものを必要としない場合、これによりアクセスが中断される可能性があります。
これを引き起こす一般的な間違いは次のとおりです。
Access-Control-Allow-Origin
および他のCORS応答ヘッダーを要求に配置しようとしています。これらはリクエストに属しておらず、何も役に立たない(自分に許可を与えることができる許可システムのポイントは何でしょうか)、応答にのみ表示される必要があります。Content-Type: application/json
とAccept
を混同している場合)の内容を記述するリクエストボディを持たないGETリクエストにContent-Type
ヘッダーを配置しようとしています。これらのいずれの場合でも、プリフライトの必要性を回避するには、多くの場合、余分なリクエストヘッダーを削除するだけで十分です。
HTTPリクエストを行う必要がある場合もありますが、レスポンスを読む必要はありません。例えば記録のためにログメッセージをサーバーに投稿する場合。
fetch
API (XMLHttpRequest
ではなく)を使用している場合、CORSを使用しないように設定できます。
これでは、CORSに必要なことは何もできません。応答を読むことができなくなります。プリフライトが必要なリクエストを行うことはできません。
シンプルなリクエストを行うことができ、レスポンスが表示されず、開発者コンソールにエラーメッセージが表示されません。
その方法は、fetch
を使用してリクエストを作成し、CORSでレスポンスを表示する権限を取得できない場合に表示されるChromeエラーメッセージで説明されています。
Origin '
https://example.com/
'から 'https://example.net
'で取得するアクセスは、CORSポリシーによってブロックされています:要求されたリソースに 'Access-Control-Allow-Origin
'ヘッダーがありません。不透明な応答がニーズを満たしている場合は、要求のモードを「no-cors」に設定して、CORSを無効にしてリソースをフェッチします。
したがって:
fetch("http://example.com", { mode: "no-cors" });
ボブは、 JSONP のようなハックを使用してデータを提供することもできます。これは、CORSが登場する前に人々がどのようにオリジンAjaxを横断したかです。
これは、データをMalloryのページに挿入するJavaScriptプログラムの形式でデータを提示することで機能します。
Malloryが悪意のあるコードを提供しないようにボブを信頼する必要があります。
共通のテーマに注意してください。データを提供するサイトは、サードパーティのサイトがブラウザに送信しているデータにアクセスしてもよいことをブラウザに伝える必要があります。
JSONPは<script>
要素を追加することで機能し、ページ内に既にある関数を呼び出すJavaScriptプログラムの形式でデータをロードするため、JSONを返すURLでJSONPテクニックを使用しようとすると失敗します。 JSONはJavaScriptではありません。
JSが実行されるHTMLドキュメントと要求されているURLが同じオリジン(同じスキーム、ホスト名、ポートを共有)にある場合、同じオリジンポリシーはデフォルトで許可を与えます。 CORSは必要ありません。
Mallorycouldは、サーバー側のコードを使用してデータを取得します(通常どおり、HTTPを介してサーバーからAliceのブラウザーに渡すことができます)。
次のいずれかです。
そのサーバー側のコードは、第三者(YQLなど)によってホストされる可能性があります。
Bobは、そのために許可を与える必要はありません。
これはマロリーとボブの間にあるので問題ありません。 BobがMalloryがAliceであると考え、MalloryにAliceとBobの間で機密にすべきデータを提供する方法はありません。
その結果、Malloryはこの手法を使用してpublicデータを読み取ることしかできません。
「同じ起源ポリシーがWebページのJavaScriptにのみ適用される理由」セクションで述べたように、WebページにJavaScriptを記述しないことで、SOPを回避できます。
これは、JavaScriptとHTMLを使い続けることができないという意味ではありませんが、Node-WebKitやPhoneGapなどの他のメカニズムを使用して配布することができます。
同一拡張ポリシーが適用される前に、ブラウザー拡張機能が応答にCORSヘッダーを挿入することが可能です。
これらは開発には役立ちますが、本番サイトでは実用的ではありません(サイトのすべてのユーザーに、ブラウザーのセキュリティ機能を無効にするブラウザー拡張機能をインストールするよう要求するのは不合理です)。
また、単純なリクエストでのみ動作する傾向があります(プリフライトOPTIONSリクエストの処理時に失敗します)。
ローカル開発serverで適切な開発環境を用意することは、通常、より良いアプローチです。
SOP/CORSは XSS 、 CSRF 、または SQLインジェクション の攻撃を緩和しないことに注意してください。独立して処理されます。
ターゲットサーバーはクロスオリジンリクエストを許可する必要があります。エクスプレスで許可するには、httpオプションリクエストを処理するだけです:
app.options('/url...', function(req, res, next){
res.header('Access-Control-Allow-Origin', "*");
res.header('Access-Control-Allow-Methods', 'POST');
res.header("Access-Control-Allow-Headers", "accept, content-type");
res.header("Access-Control-Max-Age", "1728000");
return res.sendStatus(200);
});
これは受け入れられた答えでは言及されていないので。
Simple Requests を使用できます。
「単純なリクエスト」を実行するには、リクエストがいくつかの条件を満たす必要があります。例えば。 POST
、GET
、HEAD
メソッドのみを許可し、一部の特定のヘッダーのみを許可します(すべての条件を見つけることができます here )。
クライアントコードが、リクエストに修正値を含む影響を受けるヘッダー(例: "Accept")を明示的に設定しない場合、一部のクライアントがこれらを設定することがありますmightいくつかの「非標準」値を持つヘッダーが自動的に送信されると、サーバーはそれを単純な要求として受け入れなくなります。これにより、CORSエラーが発生します。
これは、CORSエラーが原因で発生しています。 CORSはCross Origin Resource Sharingの略です。簡単に言えば、このエラーは、別のドメインからドメイン/リソースにアクセスしようとすると発生します。
詳細については、こちらをご覧ください: CORS error with jquery
これを修正するには、他のドメインにアクセスできる場合、サーバーでAccess-Control-Allow-Originを許可する必要があります。これはヘッダーに追加できます。すべてのリクエスト/ドメインまたは特定のドメインに対してこれを有効にできます。
クロスオリジンリソース共有(CORS)ポストリクエストを機能させる方法
これらのリンクは役立つかもしれません
このCORSの問題は、(他の理由で)さらに詳しくは説明されていません。
現在、この問題はさまざまな理由で発生しています。フロントエンドも 'Access-Control-Allow-Origin'ヘッダーエラーを返しています。
間違ったURLを指したため、このヘッダーが適切に反映されませんでした(その中で推測しました)。 localhost(フロントエンド)->セキュリティで保護されていないhttp(httpsを想定)への呼び出し、フロントエンドからのAPIエンドポイントが正しいプロトコルを指していることを確認します。