ホームページ > 記事 > ウェブフロントエンド > Ajax クロスドメインリクエストの解決策: JSONP を使用して JSON データを取得する
ブラウザの制限により、ajax ではクロスドメイン通信が許可されません。別のドメインからデータをリクエストしようとすると、セキュリティ エラーが発生します。データが存在するリモート サーバーを制御でき、すべてのリクエストが同じドメインに送信される場合、これらのセキュリティ上の間違いは回避できます。しかし、Web アプリケーションが独自のサーバー上に留まるだけでは、何の役に立つのでしょうか?複数のサードパーティサーバーからデータを収集する必要がある場合はどうすればよいでしょうか?
同一生成元ポリシーの制限を理解する
同一生成元ポリシーは、あるドメインに読み込まれたスクリプトが別のドメインのドキュメント プロパティを取得または操作することを防ぎます。つまり、要求された URL のドメインは、現在の Web ページのドメインと同じである必要があります。これは、ブラウザがさまざまなソースからコンテンツを分離して、ソース間での操作を防止することを意味します。このブラウザ ポリシーは古いもので、Netscape Navigator バージョン 2.0 から存在しています。
この制限を克服する比較的簡単な方法は、Web ページが元の Web サーバーにデータを要求し、Web サーバーがプロキシのように機能して、その要求を実際のサードパーティ サーバーに転送することです。このテクノロジーは広く使用されていますが、拡張性がありません。もう 1 つの方法は、フレーム要素を使用して現在の Web ページ内に新しい領域を作成し、GET リクエストを使用してサードパーティのリソースを取得することです。ただし、リソースを取得した後は、フレーム内のコンテンツは同一生成元ポリシーによって制限されます。
この制限を克服するより理想的な方法は、ソースが別のドメインのサービス URL を指す動的スクリプト要素を Web ページに挿入し、独自のスクリプトでデータを取得することです。スクリプトが読み込まれると実行が開始されます。このアプローチが機能するのは、同一生成元ポリシーによって動的なスクリプトの挿入が妨げられず、スクリプトが Web ページを提供するドメインから読み込まれたかのように扱われるためです。ただし、スクリプトが別のドメインからドキュメントをロードしようとすると、成功しません。幸いなことに、この手法は JavaScript Object Notation (JSON) を追加することで改善できます。
JSONPとは何ですか?
JSONP を理解するには、JSON について触れなければなりません。それでは、JSON とは何でしょうか?
JSONP (JSON with Padding) は、サーバー側でスクリプト タグを統合してクライアントに返すことを可能にする非公式のプロトコルで、JavaScript コールバックを介してクロスドメイン アクセスを実現します (これは単なる JSONP の実装です)。
JSONP は何に使用されますか?
同一オリジン ポリシーの制限により、XmlHttpRequest では現在のソース (ドメイン名、プロトコル、ポート) からのリソースのリクエストのみが許可されます。クロスドメイン リクエストを実装するには、スクリプトを使用してクロスドメイン リクエストを実装します。タグを作成し、サーバー上に JSON データを出力し、コールバック関数を実行してクロスドメイン データ リクエストを解決します。
JSONPの使用方法?
以下のデモは、実際には JSONP の単純な表現です。クライアントがコールバック関数を宣言した後、クライアントはスクリプト タグを通じてサーバーにクロスドメイン データを要求し、サーバーは対応するデータを返し、コールバック関数を動的に実行します。 。
1. HTML コード (いずれか):
<meta content=“text/html; charset=utf-8″ http-equiv=“Content-Type” /> <script type=“text/javascript”> function jsonpCallback(result) { //alert(result); for(var i in result) { alert(i+”:”+result[i]);//循环输出a:1,b:2,etc. } } var JSONP=document.createElement(“script”); JSONP.type=“text/javascript”; JSONP.src=“http://crossdomain.com/services.php?callback=jsonpCallback”; document.getElementsByTagName(“head”)[0].appendChild(JSONP); </script>
または
<meta content=“text/html; charset=utf-8″ http-equiv=“Content-Type” /> <script type=“text/javascript”> function jsonpCallback(result) { alert(result.a); alert(result.b); alert(result.c); for(var i in result) { alert(i+”:”+result[i]);//循环输出a:1,b:2,etc. } } </script> <script type=“text/javascript” src=“http://crossdomain.com/services.php?callback=jsonpCallback”> </script>
JavaScript リンクは関数の下にある必要があります。
2. サーバーサイドのPHPコード
<?php //服务端返回JSON数据 $arr=array(‘a’=>1,‘b’=>2,‘c’=>3,‘d’=>4,‘e’=>5); $result=json_encode($arr); //echo $_GET['callback'].’(“Hello,World!”)’; //echo $_GET['callback'].”($result)”; //动态执行回调函数 $callback=$_GET[‘callback’]; echo $callback.“($result)”;
3. jQueryの実装
jQueryでのクライアントJSコードの実装方法1:
<script type=“text/javascript” src=“jquery.js”></script> <script type=“text/javascript”> $.getJSON(“http://crossdomain.com/services.php?callback=?”, function(result) { for(var i in result) { alert(i+“:”+result[i]);//循环输出a:1,b:2,etc. } }); </script>
jQueryでのクライアントJSコードの実装方法2:
<script type=“text/javascript” src=“jquery.js”></script> <script type=“text/javascript”> $.ajax({ url:“http://crossdomain.com/services.php”, dataType:‘jsonp’, data:”, jsonp:‘callback’, success:function(result) { for(var i in result) { alert(i+“:”+result[i]);//循环输出a:1,b:2,etc. } }, timeout:3000 }); </script>
クライアントJSの実装方法3 jQueryのコード:
<script type='text/javascript' src='jquery.js'></script> <script type='text/javascript'> $.get('http://crossdomain.com/services.php?callback=?', {name: encodeURIComponent('tester')}, function (json) { for(var i in json) alert(i+':'+json[i]); }, 'jsonp'); </script>
このうち、jsonCallbackはクライアントによって登録され、クロスドメインサーバー上のjsonデータを取得した後のコールバック関数です。
http://crossdomain.com/services.php?callback=jsonpCallback
この URL は、クロスドメイン サーバーから JSON データを取得するためのインターフェイスです。パラメータはコールバック関数の名前です。返される形式は
jsonpCallback({msg:'this is json data'})
jsonp です。原則:
まずクライアントでコールバックを登録します。コールバック名をサーバーに渡します。
この時点で、サーバーは最初に json データを生成します。
次に、JavaScript 構文を使用して関数を生成します。関数名は渡されたパラメーター jsonp です。
最後に、json データがパラメーターとして関数に直接配置され、js 構文ドキュメントが生成され、クライアントに返されます。
クライアントのブラウザはscriptタグを解析し、返されたJavaScriptドキュメントを実行します。このとき、データはクライアントによって事前に定義されたコールバック関数にパラメータとして渡されます(コールバック関数の動的実行)。
JSON を使用する利点は次のとおりです:
XML よりもはるかに軽く、冗長なものがあまりありません。
JSON も非常に読みやすいですが、通常は圧縮されて返されます。ブラウザーで直接表示できる XML とは異なり、ブラウザーはいくつかのプラグインを使用して JSON をフォーマットする必要があります。
JavaScript での JSON の処理は簡単です。
PHP などの他の言語も JSON を適切にサポートしています。
JSON にはいくつかの欠点もあります。
JSON のサーバー側言語サポートは XML ほど広範囲ではありませんが、JSON.org は多くの言語のライブラリを提供しています。
eval() を使用して解析すると、セキュリティ上の問題が発生しやすくなります。
それにもかかわらず、JSON の利点は依然として明白です。これは、Ajax データ対話に理想的なデータ形式です。
重要なヒント:
JSONP はマッシュアップを構築するための強力なテクノロジーですが、残念ながら、すべてのクロスドメイン通信のニーズに対応する万能薬ではありません。これにはいくつかの欠陥があるため、開発にリソースを投入する前に慎重に検討する必要があります。
まず、そして最も重要なことは、JSONP 呼び出しにはエラー処理がありません。動的スクリプトの挿入が有効な場合、呼び出しは実行されます。無効な場合、呼び出しはサイレントに失敗します。失敗に対するプロンプトはありません。たとえば、404 エラーはサーバーから捕捉できず、リクエストをキャンセルしたり再開したりすることはできません。ただし、しばらく待っても応答がない場合は無視してください。 (jQuery の将来のバージョンには、JSONP リクエストを終了する機能が搭載される可能性があります)。
JSONP のもう 1 つの大きな欠点は、信頼できないサービスで使用すると危険になる可能性があることです。 JSONP サービスは、ブラウザーによって実行される関数呼び出しにラップされた JSON 応答を返すため、ホスト Web アプリケーションはさまざまな攻撃に対してより脆弱になります。 JSONP サービスを使用する予定がある場合は、それがもたらす可能性のある脅威を理解することが重要です。