ホームページ > 記事 > ウェブフロントエンド > JSONPの実装原理
今回は、JSONP の実装原則と、JSONP を使用する際の 注意事項 について説明します。実際のケースを見てみましょう。
JSONPの実装原理 フロントエンドとバックエンドの分離に携わっている多くの人がJSONPに触れることが多いと思いますが、多くの初心者はJSONPの実装方法とその実装原理を知りません。という記事で詳しく紹介していますので、興味のある方はぜひご覧ください。 基本原則 基本原理は簡単に説明できます。img、script、link など、HTML ページにはクロスドメイン制限を受けないタグがいくつかあります。必要なデータを js ファイルに入れると、ブラウザーの同一オリジン制限を突破できます。 スクリプトタグを作成します 動的スクリプト要素については、「ハイパフォーマンスJavaScript」で言及されており、著者は次のように書いています:
1. 要素がページに追加されると、ファイルのダウンロードが開始されます。この手法の重要な点は、ダウンロードが開始されるたびに、ファイルのダウンロードと実行がページ上の他のプロセスをブロックしないことです。 2. 動的スクリプト ノードを使用してファイルをダウンロードする場合、通常、返されたコードはすぐに実行されます (Firefox と Oprea を除く。これらのノードは、以前のすべての動的スクリプト ノードの実行が完了するまで待機します)。スクリプト自体が実行されると、このメカニズムは正常に動作します。 。 コールバック GET リクエストを受信した後、サーバーは通常、コールバック パラメータがあるかどうかを判断し、コールバック パラメータがある場合は、返されたデータの外側にメソッド名と括弧を追加する必要があります。たとえば、次のリクエストを実行します:http://www.a.com/getSomething?callback=jsonp0その後、サーバーは次のコンテンツを返します:
jsonp0({code:200,data:{}})明らかに、これは動的にロードされる Script タグに含まれるコンテンツであるため、これは自己実行コードの一部であり、このコードの 1 つの関数のみが呼び出されます - jsonp0。 もちろん、実行がある場合は、最初に作成する必要があります。そうしないと、エラーが報告されます。この作成ステップは、呼び出す前に実行する必要があります。 具体的な実装は次のとおりです:
function jsonp (url, successCallback, errorCallback, completeCallback) { // 声明对象,需要将函数声明至全局作用域 window.jsonp0 = function (data) { successCallback(data); if (completeCallback) completeCallback(); } // 创建script标签,并将url后加上callback参数 var script = document.createElement('script') , url = url + (url.indexOf('?') == -1 ? '?' : '&') + 'callback=jsonp0' ; script.src = url; document.head.parentNode.insertBefore(script, document.head); // 等到script加载完毕以后,就会自己执行 }以上で基本的に jsonp メソッドの中核部分が完成します。この時点で jsonp0 は宣言した関数であり、サーバーが正常に戻ると jsonp0 関数が実行され、内部の successCallback コールバックも実行されます。 改善してください 実際の状況では、通常、同時に多くの jsonp リクエストが呼び出されます では、jsonp0 はニーズを満たすことができるのに、jsonp1、jsonp2 などのコードが順番に蓄積されることがよくあるのはなぜでしょうか。 これは、多くのリクエストが非同期で行われる可能性があるためです。初めてjsonpメソッドを実行するときは、window.jsonp0が関数Aになります。このとき、jsファイルが読み込まれます。jsが読み込まれていない場合は、再度jsonpメソッドが呼び出されます。機能B。次に、2 つの js がロードされた後、2 番目のコールバックが実行されます。 したがって、コールバックの名前で区別する必要があり、蓄積することでニーズを満たすことができます。 コードを変更します:
var jsonpCounter = 0; function jsonp (url, successCallback, errorCallback, completeCallback) { var jsId = 'jsonp' + jsonpCounter++; // 声明对象,需要将函数声明至全局作用域 window[jsId] = function (data) { successCallback(data); if (completeCallback) completeCallback(); clean(); } // 创建script标签,并将url后加上callback参数 var script = document.createElement('script') , url = url + (url.indexOf('?') == -1 ? '?' : '&') + 'callback=' + jsId ; script.src = url; document.head.parentNode.insertBefore(script, document.head); // 等到script加载完毕以后,就会自己执行 //在执行完我们这个方法以后,会有很多script标签出现在head之前,我们需要手动的删除掉他们。 function clean () { script.parentNode.removeChild(script); window[jsId] = function(){}; } }蓄積とクリーンアップを追加した後、処理する必要があるもう 1 つの重要な点があります。それはエラー コールバックです。通常、jsonp をリクエストするとタイムアウトが設定され、この時間を超えるとタイムアウト例外がスローされます。 次のように実装されます:
var jsonpCounter = 0; function jsonp (url, successCallback, errorCallback, completeCallback, timeout) { // 略去上面写过的代码 var timeout = timeout || 10000 , timer ; if (timeout) { timer = setTimeout(function () { if (errorCallback) { errorCallback(new Error('timeout')); } clean(); }, timeout) } function clean () { script.parentNode.removeChild(script); window[jsId] = function(){}; if (timer) clearTimeout(timer); } }このようにして、jsonp のすべての機能は基本的に完成しますが、完全な jsonp メソッドとみなされるためには、残りの部分に互換性のある変更が必要になる場合があります。 参照してくださいこの記事の事例を読んだ後、あなたはその方法を習得したと思います。さらに興味深い情報については、php 中国語 Web サイトの他の関連記事に注目してください。 推奨読書:
以上がJSONPの実装原理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。