クロスドメイン原則JSONP

JSONPクロスドメインの原則:https://www.cnblogs.com/willing-shang/p/6719875.html

 

1.はじめに


JSONPがクロスドメインの一般的な手段である、とに比べてクロスドメインプロセスを実行するためにリバース・プロキシ・サーバー、さらに便利JSONPと軽量、彼らはクロスドメインリクエストを大量に処理するために使用されてきたが、その後、この要求は最終的には方法ですどのような黒魔術、私たちのクロスドメインの問題を解決するための頭痛の種を作ります。

2.原理


実際にJSONPは、この効果のクロスドメインを達成するために、黒魔術のない使用は、スクリプトタグ自体を使用すると、クロスドメイン機能以外の何ものでもありません。私たちは、ダウンロードがこの意志すぐにJS完了し、その後の後、IMG、スクリプト、このラベルに対応するSRCがある場合、スクリプトタグに対応するパスがあれば、それは、適切なリソースを要求するhtttp要求を開始しますが、JSファイルで、知っています実行

< スクリプト  タイプ= "テキスト/ javascriptの"  SRC = "www.somewhere.com/test.js"> </ スクリプト>
<! - ダウンロードが完了した後に、この時間は、test.jsを取得するための要求を開始しますすぐにtest.js実行されます - >


私たちは、AJAX要求を開始する必要がある場合は、ブラウザの相同保護制限ポリシーので、要求をデータ「www.somewhere.com/getdata」を取得するための要求を開始するために「www.localhost.com」から必要があるとします戻り値は、クロスドメインの問題であり、ブラウザによって受け付けられません。しかし、このスクリプトタグは、get要求を開始し、要求が同一生成元ポリシーの制限の対象ではない、と私たちは次のようになるための要求を送信するためのスクリプトタグに「www.somewhere.com/getdata」意志があれば、そうではありません何のクロスドメインの問題はないだろう

 

< スクリプト  タイプ= "テキスト/ javascriptの"  SRC = "www.somewhere.com/getdata"> </ スクリプト>
<! - GETリクエストを開始するためのスクリプトを必要とします - >




答えはイエスであり、これはクロスドメインのJSONPの原理です。しかし同時に、まず、リクエストを送信するために、スクリプトを使用する方法、データを取得するための第2の要求が受信され、どのようにフロントページ上で処理されるように、ここでは二つの問題がありました。我々は通常発生したとき、最初の質問のために、私たちは一般的に、我々は、事前にhtmlタグで書かれたオリジナルと同じを持っている場合、ブラウザが文書を解析し、動的なリクエストとなり、HTMLドキュメント内のスクリプトタグを記述しますこのスクリプトタグは、直ちに、そのような私たちは、これらのデータを使用する場合、良好な負荷データのフロントを探して、要求を開始しますと、これは明らかにあまりにも時間がかかり、柔軟性に劣る、とページ多くの要求がある場合は、希望ではありませんページ上のこれらの多くのスクリプトタグを進めるために、醜いこのページでは、単純に読み取ることができません。必要なのはサービスを要求し、その要求を開始したとき、我々は、動的スクリプトタグを作成するには、達成するためにトンドのdocument.createElementをダイナミックタグを使用することができ、その後、要求が完了した後などにそのsrc属性を設定して、スクリプトですラベルを削除し、その後、最初の問題が解決されます。

 

聞かせてスクリプト=  のdocument.createElement('スクリプト');
srcipt.src =  'www.somewhere.com/getdata';
document.querySelector('ヘッド')のappendChild(スクリプト)。




しかし同時に、それはまた、2つ目の質問、リクエストが完了したときにどのように我々は知っている、バックデータが処理され、ラベルを削除する方法の要求が完了した後にされた方法への要求がありました。あまりにも先に述べたようにスクリプトタグがダウンロードされます後、すぐに(非同期と一時的に控える延期)実行され、私たちの要求は通常、{「名前」として、エラーにJSONオブジェクトが、JSON直接実行を返します。 「劉侯光」、「ジョブ」:それは、{が「FE」}声明文で括弧は、括弧の内容は、ステートメントブロックとして認識される場合は、括弧の外側の層は単に無視されます。名前:「劉侯光」、仕事:「FE」}でも、中括弧を無視するため、このフォームは、エラーではないかもしれ名:「劉侯光が」正当なjsの声明で、ラベル文と呼ばれますが、としてそこに引用符で囲まれたラベルへのステートメントは、「名前」、以下のとおりです。「侯劉光」が、ラベル文を引用符で囲むことができないため、この形式は、有効ではありませんが、キーJSONが、二重引用符で囲む必要がありますので、直接JSONを返すことは十分ではありません、我々は、ジョブの実行可能ファイルjsのステートメントに戻らなければなりません。そして、一般的に、我々は、我々がどのような結果がそれの組み合わせで返され、論理演算を記述し、いくつかのJSを実行するために論理演算の結果を要求する必要がありますか?それがコールバックを必要とするこの時間が果たしました。私たちは、「パッケージ化」の外観の結果を要求することができ、処理ロジックデータが関数に書き込まれ、その後、スクリプトの結果は、この関数を呼び出すために、データをこの関数に渡す必要があり、その後、すべての問題を解決することができます。{「侯劉光」、「仕事」:「名前」「FE」}と仮定する要求結果の含有量は、処理関数の結果がコールバックと呼ばれています

//処理、コールバック関数、または割り当ての結果は、スクリプト要求の前にページ内で宣言されている必要があります
関数  コールバック(データ){
console.log(data.name)
}
 
 
コールバック関数があるとスクリプトは、JSファイルを返さなければなりません//注、関数呼び出しの形で要求フォームの結果をラップします
//ファイルの内容
コールバック({ "名":  "柳轻侯"、  "仕事":  "FE"})


しかし、複数のJSONPリクエストページならば、我々はすべてのコールバック関数コールバックにそれを呼び出すことはできませんので、この時間は、あなたは、コールバック関数、異なるJSONP要求コール異なるコールバック関数の名前を指定する必要があります。サーバーに渡されたスクリプト関数名、およびパッケージ名を指定して、この関数の結果に対応するサーバの要求、そしてあなたが名前で呼び出すことができるように、フロントエンドに戻ります。私たちは、シンプルなパッケージでの要求を行います。

関数  getJSONP(URL、コールバック){
聞かせてスクリプト=  のdocument.createElement('スクリプト');
script.type =  "タイプ="テキスト/ javascriptの。
srcipt.src = URL +  '?コールバック=' +コールバック。
document.querySelector('ヘッド')のappendChild(スクリプト)。
}


この時間は、2つの要求は、処理、「www.somewhere.com/getdata1」が必要とされ、「www.somewhere.com/getdata2」2つの要求は、要求の処理結果を必要{「名前」である場合:「光劉侯」 、 "仕事": "FE"}と{ "名前": "日唐"、 "仕事": "FE"}、ハンドラはdealData1とdealData2あり、私たちはどのように対処しますか?

 

関数  getJSONP(URL、コールバック){
聞かせてスクリプト=  のdocument.createElement('スクリプト');
script.type =  "タイプ="テキスト/ javascriptの。
srcipt.src = URL +  '?コールバック=' +コールバック。
document.querySelector('ヘッド')のappendChild(スクリプト)。
}
 
CONST dealData1 =  関数(データ){
(にconsole.log 'getData1コールバックである:' + data.name)。
}
CONST dealData2 =  関数(データ){
(にconsole.log 'getData1コールバックである:' + data.name)。
}
 
//リクエストが送信されます
getJSONP( 'www.somewhere.com/getdata1', 'dealData1'); // www.somewhere.com/getdata1?callback=dealData1
getJSONP( 'www.somewhere.com/getdata2', 'dealData2'); // www.somewhere.com/getdata1?callback=dealData2



// 请求结果分别是
dealData1({ "name": "柳轻侯", "job": "FE"})
dealData2({ "name": "天棠", "job": "fe"})
 
//执行结果
这是getData1的回调: 柳轻侯
这是getData2的回调: 天棠




这时候两个结果会分别用传过去的callback来包装,然后输出不同的结果,这时候我们的需求基本上被满足了,最后还要处理的一点,每发一条请求,页面上被凭空创建了一个script标签,如果有请求很多,那么页面上就会多出很多无意义的标签(请求结束之后相应的标签就失去了意义),所以我们需要在请求处理结束之后清除创建的script标签。但是页面上还有别的script标签,必须只清除当前请求的jsonp生成的标签,如果将其他的script标签,可能就会造成其他的严重问题。由于每个jsonp的回调函数名称不一样,我们可以通过回调函数名来找出我们想要清除的script。

const dealData1 = function (data) {
console.log('这是getData1的回调:' + data.name);
// 处理完毕之后清除相应的script标签
let callbackName = arguments.callee.name;
document.querySelector('script[src*="callback=' + callbackName + '"]').remove();
}

3. jsonp的缺点

      • 只能发送get请求。因为script只能发送get请求
      • 需要后台配合。此种请求方式应该前后端配合,将返回结果包装成callback(result)的形式。

おすすめ

転載: www.cnblogs.com/bydzhangxiaowei/p/11622481.html