web-dev-qa-db-ja.com

基本AJAX要求は「 'Access-Control-Allow-Origin'ヘッダーが要求されたリソースに存在しません」というエラーを取得します」エラー

JQuery AJAXリクエスト)の特定のリンクに、単にGETリクエストを送信しようとしました。

それは非常に簡単なものです:

$.ajax({
    type: 'GET',
    url: /* <the link as string> */,
    dataType: 'text/html',
    success: function() { alert("Success"); },
    error: function() { alert("Error"); },
});

しかし、私が試したものは何でも、XMLHttpRequest cannot load <page>. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:7776' is therefore not allowed access.

AJAXリクエストにheader : {}定義を追加することから、単純な=を使用してdataTypeJSONPに、またはtext/plainに設定することまで、すべてを試しました。 AJAX jQueryの代わりに、CORSを有効にするプラグインをダウンロードすることもできますが、何も解決できません。

そして、他のサイトにアクセスしようとしても同じことが起こります。

適切でシンプルなソリューションのアイデアはありますか?何かありますか?

12
Zoltán Schmidt

これは仕様です。 XMLHttpRequestを使用して別のサーバーに任意のHTTP要求を行うことはできません。ただし、そのサーバーが要求元のホストにAccess-Control-Allow-Originヘッダーを送信して許可しない限り、この要求を行うことはできません。

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

スクリプトタグで取得することもできます(スクリプト、画像、スタイルシートには同じ制限はありません)が、返されるコンテンツがスクリプトでない限り、あまり役に立ちません。

CORSのチュートリアルは次のとおりです。

http://www.bennadel.com/blog/2327-cross-Origin-resource-sharing-cors-ajax-requests-between-jquery-and-node-js.htm

これはすべて、エンドユーザーを保護するために行われます。画像が実際に画像であると仮定すると、スタイルシートは単なるスタイルシートであり、スクリプトは単なるスクリプトであり、これらのリソースを別のサーバーに要求しても実際には害はありません。

しかし一般的に、クロスオリジンのリクエストは本当に悪いことをすることができます。 Zoltanがcoolsharks.comを使用しているとしましょう。また、mybank.comにログインしており、ブラウザにmybank.comのCookieがあることを伝えます。次に、coolsharks.comがAJAXリクエストをmybank.comに送信し、すべてのお金を別のアカウントに送金するように要求したとします。 mybank.com Cookieが保存されているため、リクエストは正常に完了します。また、ページのリロードが発生しなかったため、これらすべてはユーザーの知らないうちに発生します。これは、一般的なクロスサイトAJAXリクエストを許可する危険です。

クロスサイトリクエストを実行する場合、2つのオプションがあります。

  1. リクエストを行っているサーバーを取得します
    a。あなた(または*)を含むAccess-Control-Allow-Originヘッダーを出すことであなたを認めます
    b。 JSONP APIを提供します。

または

  1. 標準に準拠せず、制限のない独自のブラウザを作成します。

(1)では、リクエストを行うサーバーの協力が必要です。(2)では、エンドユーザーのブラウザを制御する必要があります。 (1)または(2)を満たせない場合は、ほとんど運がありません。

ただし、3番目のオプションがあります(charlietflが指摘)。制御するサーバーから要求を作成し、結果をページに戻すことができます。例えば。

<script>
$.ajax({
    type: 'GET',
    url: '/proxyAjax.php?url=http%3A%2F%2Fstackoverflow.com%2F10m',
    dataType: 'text/html',
    success: function() { alert("Success"); },
    error: function() { alert("Error"); }
});
</script>

そして、あなたのサーバー上で、その最も簡単なもので:

<?php
// proxyAjax.php
// ... validation of params
// and checking of url against whitelist would happen here ...
// assume that $url now contains "http://stackoverflow.com/10m"
echo file_get_contents($url);

もちろん、この方法では他の問題が発生する可能性があります。

  • プロキシのサイトには、正しいリファラーまたは特定のIPアドレスが必要ですか?
  • Cookieをターゲットサーバーに渡す必要がありますか?
  • ホワイトリストは、任意のリクエストを行うことからあなたを十分に保護していますか?
  • サーバーがヘッダーを受け取ったときに、どのヘッダー(時刻の変更など)をブラウザーに返しますか。どのヘッダーを省略または変更しますか?
  • (プロキシとして動作しているため)サーバーが違法なリクエストを行ったとみなされますか?

他にもあると思います。しかし、これらの問題のいずれもそれを妨げない場合、この3番目の方法は非常にうまく機能します。

7
Chris Middleton

適切なヘッダーを設定するかどうかをそのドメインの開発者に尋ねることができます。この制限はjavascriptのみに適用されます。

3
john Smith