ホームページ  >  記事  >  ウェブフロントエンド  >  JSONPの実装原理

JSONPの実装原理

php中世界最好的语言
php中世界最好的语言オリジナル
2018-04-14 17:29:371534ブラウズ

今回は、JSONP の実装原則と、JSONP を使用する際の 注意事項 について説明します。実際のケースを見てみましょう。

JSONPの実装原理

フロントエンドとバックエンドの分離に携わっている多くの人がJSONPに触れることが多いと思いますが、多くの初心者はJSONPの実装方法とその実装原理を知りません。という記事で詳しく紹介していますので、興味のある方はぜひご覧ください。

基本原則

基本原理は簡単に説明できます。img、script、link など、HTML ページにはクロスドメイン制限を受けないタグがいくつかあります。必要なデータを js ファイルに入れると、ブラウザーの同一オリジン制限を突破できます。

スクリプトタグを作成します

動的スクリプト要素については、「ハイパフォーマンス

JavaScript」で言及されており、著者は次のように書いています:

1. 要素がページに追加されると、ファイルのダウンロードが開始されます。この手法の重要な点は、ダウンロードが開始されるたびに、ファイルのダウンロードと実行がページ上の他のプロセスをブロックしないことです。

2. 動的スクリプト ノードを使用してファイルをダウンロードする場合、通常、返されたコードはすぐに実行されます (Firefox と Oprea を除く。これらのノードは、以前のすべての動的スクリプト ノードの実行が完了するまで待機します)。スクリプト自体が実行されると、このメカニズムは正常に動作します。 。

Quote1 は、JSONP リクエストを行うときにメインスレッドがブロックされないことを保証します。Quote 2 は、ロードの完了直後に JSONP コード自体が実行されるときにエラーが発生しないことを保証します。

コールバック

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 サイトの他の関連記事に注目してください。

推奨読書:

vue-routerコンポーネント間でパラメータを渡す方法

Vue.jsモバイルコンポーネントライブラリの使用方法

以上がJSONPの実装原理の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。