web-dev-qa-db-ja.com

jQuery-クロスドメイン制限を削除する方法

私はモバイル用のWebアプリに取り組んでおり、jsonpはクロスドメインリクエストに対してかなりクールですが、サーバーのAPIはコールバックパラメーターをサポートしていませんでした。したがって、jsonを使用してリモートサーバーからデータをフェッチできます。

JQueryでjsonを試しましたが、クロスドメインリクエストをサポートしていないようです。サファリで生のajaxリクエスト関数を試しましたが、クロスドメインでうまく機能しますが、jQueryでjsonリクエストのクロスドメインの制限を削除できますか? (jsonpではなくjsonのみ)、そしてそれを行う方法は?

または、代替の単純なajaxライブラリ(クロスウェブブラウザ)があり、クロスドメインリクエストでjsonを実行できます。

12
Tom

Same Origin Policy

同一生成元ポリシー を回避しようとしています。これはすべてのブラウザーに組み込まれており、通常は無効化/回避策などを実行できる、または実行したくないものではありません。これは、サイト、ユーザー、およびユーザーのブラウザー間の非常に重要なセキュリティ契約です。

CORS(可能性あり)

[〜#〜] cors [〜#〜] Webサーバーは、別のドメインへのアクセスが許可されていることをブラウザー/クライアントに通知できます。これは、Webサーバーが次のHTTPヘッダーを出力することによって行われます。

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

HTTPヘッダーを制御できない場合、CORSを使用することはできません。これの実装は言語/フレームワーク固有です。

IE8/9のサポートには制限があったため、 ブラウザの互換性 を確認してください。これは潜在的な攻撃ベクトルであることにも注意してください。応答データを無責任に使用した場合、サードパーティサイトからの応答がXSS攻撃を実行できるようにします。

JSONP(可能)

[〜#〜] jsonp [〜#〜] は、scriptタグとsrc属性が等しいタグを動的に追加することにより、サーバー間でデータをやり取りする賢い方法です。 to "yoururl.com?<your parameter data>"あなたのページに。これは、Webプロキシ(以下を参照)またはアプレット(Flash/Java)なしでこのような偉業を達成する唯一の正当な方法です。ただし、リクエストの両端のプロバイダーでない場合は、独自のセキュリティリスクがあります。 JSONPを使用すると、リモートサーバーがコンテキスト内でコードを実行できるため、 誰にその権限を与えるかについては十分注意してください である必要があります。

"バニラ" AJAX(不可能)

JSONPを使用してデータをフェッチしていない場合は、AJAXリクエストを使用してデータをフェッチしようとしている可能性があります。AJAXリクエストも対象になります同一生成元ポリシー。JavaScriptライブラリ(jQuery、Prototype、Dojoなど)は、Ajaxリクエストの基本動作としてこのポリシーを回避することはできませんが、JSONPをサポートできます(現在はAJAXではありません)。

Webプロキシ付きAJAX(可能)

別のサーバーからデータを要求したい場合は、要求を転送できます。メインサイトのサーバーがプロキシとして機能します。自分のサーバーにAJAXリクエストを送信する必要があります。そのサーバー側のコードは、他のドメインにリクエストを送信し、AJAXは応答を呼び出します。

これは一般的なパターンであり、ここでは Webプロキシパターン および価格設定に適したYahooのもの ただし、ここでは(ただし、Yahoo固有であることを忘れないでください。一般的な考え方を採用してください) として詳しく説明します。ただし、サーバー側の言語に依存します。全体的な実装は同じですが、そのためのコードは、選択したサーバー側の言語(PHP、Ruby、Python、Cなど)によって異なります。一部の言語には、そのようなパターンをサポートするためのライブラリ/モジュールなどがすでにあります。

Flash(可能、デフォルト以外)

デフォルト状態のFlashは、クロスドメインリクエストをサポートしていません。 Flash7 +では クロスドメインポリシーファイル でオンにできますが、使用しないことを強くお勧めします。スクリプトは、リクエストを作成してデータをJavaScriptに返すFlashAPIとインターフェースする必要があります。

Javaアプレット(可能、デフォルト以外)

Javaも同じOriginポリシーの対象ですが、Flashと同様の回避策があります リリースでここに説明されています

その他のさまざまな「ハッキング」

他にもハックはありますが、一般的には両端を制御するか、通信の標準に合意する必要があります。たとえば、「window.name」ハック。これらの方法のほとんどはお勧めしません。

その他のソリューション

これに似た別の質問がありました。それは私がカバーしなかった他のいくつかの方法を概説します: 同一生成元ポリシーを回避する方法

ベストソリューション

  1. CORS-サードパーティを信頼する場合
  2. Webプロキシ-そうでない場合

独自のドメインのWebプロキシを使用すると、取得するデータをサニタイズでき、ユーザーを最大限に保護できます。ただし、衛生設備をゼロにすると、ここで概説したどの方法よりも安全ではありません。ある種のWebプロキシを実装する場合は、その要求が目的のサイトに限定されていることを確認してください。それ以外の場合は、本質的に オープンプロキシ を作成します。発見された場合、ユーザーによって悪用され、法的な問題に巻き込まれる可能性があります。

33
Andrew Martinez

私も同じ問題を抱えていました。サーバーからjsonを取得しようとして、アクセスできませんでした(=> JSONPがありません)。

私は見つけました http://benalman.com/projects/php-simple-proxy/ サーバーにphpプロキシを追加し、このファイルに対してajax呼び出しを行います。 「リモートURLリソースに渡されるGETパラメーターはすべて、このパラメーターにurlencodedする必要があります。」

$.ajax({
   type: 'GET',
   url:'proxy.php?url=http://anyDomain.com?someid=thispage',
   dataType: "json",
   success: function(data){
      // success_fn(data);
   },
   error: function(jqXHR, textStatus, errorThrown) {
      // error_fn(jqXHR, textStatus, errorThrown);
   }
});

proxy.php(Ben Almanのファイル)がドメインでホストされている場所


別の方法(これに2番目に適していることがわかりました): http://james.padolsey.com/javascript/cross-domain-requests-with-jquery/

6
Symba

それを行うためのかなり厄介な方法は、個人的なプロジェクトでクロスサイト実行を可能にするために私が以下で行ったことです

これは送信サーバーではなく受信サーバーで行われることに注意してください

    if ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') === FALSE)
        die('You shouldn\'t be here');

    header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_Origin']);
    header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
    header('Access-Control-Max-Age: 1000');
    header('Access-Control-Allow-Headers: Content-Type');

もう少し安全にしたいなら

    if ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') === FALSE)
        die('You shouldn\'t be here');

switch($_SERVER['HTTP_Origin']){
case 'domain.com':
case 'whatever.com':
        header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_Origin']);
        header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
        header('Access-Control-Max-Age: 1000');
        header('Access-Control-Allow-Headers: Content-Type');
}

これがそれを理解するのに永遠にかかったのを助けてくれることを願っています.

4
Clark T.