JSONP原理による解析(推奨)

4166 ワード

前言
私が仕事してから接触した最初の項目は前後の端で分離しています。先端の静的なファイルは自分の独立したドメイン名があります。インタフェースを通じてデータを取得してレンダリングなどの操作をしています。
ドメインにまたがる方法は多くの言葉を必要としないで、気軽に探して、たくさんあって、しかし最も常用するのはjsonpとCORSだけです。jsonpは先端に重点を置いています。先端のHackテクニックとも言えます。CORSは後端より重く、サービス側の配置が必要なところが多いです。
この記事はjsonpの実現原理を解析します。
基本原理
基本原理は分かりやすいです。これまでのページにはドメイン制限を受けないタグがあります。例えば、script、linkなどです。私たちが必要なデータをjsファイルに入れると、ブラウザのソース制限を突破できます。
スクリプトタグを作成
「高性能JavaScript」では動的脚本の要素に言及しています。
1、ファイルはこの要素がページに追加された時にダウンロードを開始します。この技術のポイントは、いつからダウンロードを開始しても、ファイルのダウンロードと実行はページの他のプロセスをブロックしないことです。
2、ダイナミックスクリプトノードを使ってファイルをダウンロードすると、返ってくるコードは通常すぐに実行されます。(FirefoxとOpreaを除いて、これまでのすべてのダイナミックスクリプトノードの実行が完了するのを待ちます。)スクリプトが自己実行されると、このメカニズムは正常に動作します。
参照1は、JSONP要求時にメインスレッドをブロックしないことを保証し、参照2は、JSONPコードがロード完了後、直ちに自己実行時にエラーが発生しないことを保証しています。
calback
サービス側はGET要求を受信した後、通常calbackパラメータがあるかどうかを判断します。もしあるなら、戻りデータの外に方法名と括弧を追加する必要があります。例えば、以下の要求が開始される。

http://www.a.com/getSomething?callback=jsonp0
そうすると、次の内容に戻ります。

jsonp0({code:200,data:{}})
明らかに、動的にロードされたScriptタグに含まれる内容であるため、これは自己実行コードであり、このコードは一つの関数だけで呼び出されます。
もちろん実行があれば、まず作成しなければなりません。そうでなければエラーが発生します。このステップを作成するには、呼び出し前に実行する必要があります。
具体的な実現は以下の通りです。

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方法の核心を完成しました。この时、jccess Callbackも実行します。
完全にしてください
実際には、多くのjsonpの要求が同時に呼び出されます。
じゃ、jsong 0は私達の需要を満たすことができます。どうしていつもjson 1、jsop 2などの順番に積み重ねるコードを見ますか?
なぜなら、要請は多くの非同期的なものかもしれないからです。jsonメソッドを初めて実行した時、window.jsop 0は関数Aで、この時jsファイルをロードして、jsがロードし終わっていない場合、もう一度jsop方法を呼び出しました。この時、window.json 0は関数Bを指しました。二回のjsのロードが終わったら、二回目のコールバックを行います。
だから、私達はcalbackの名前に対して区別して処理しなければなりません。積算すれば、需要を満たすことができます。
コードを変更します。

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(){};
 }
}
アキュムレスとクリーンアップを加えた後、もう一つ重要なところは処理が必要です。普通、私達は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の全部の機能を完成しました。残りはいくつかの互換性のある修正をする必要があります。
REFER
『高性能JavaScript』
npmでjsonpを実現しました。JSONPです。
以上のJSONP原理解析(オススメ)に基づいて、小編集が皆さんに提供している内容を全部共有します。参考にしてほしいです。よろしくお願いします。