jsonpは皆さんよく使っていると思いますが、jsonpを使う機会はあまりなく、「クロスドメインに使われる」ということだけは知っていて、それが何なのか全く知りませんでした。今日やっと分かりました。 jsonp とは何かを段階的に理解してみましょう。
同一生成元ポリシー
まず、セキュリティ上の理由から、ブラウザには同一生成元ポリシーと呼ばれるメカニズムがあり、同一生成元ポリシーにより、あるソースからロードされたドキュメントまたはスクリプトが別のソースからロードされたドキュメントの属性を取得または設定することができなくなります。意味が分からないようですが、練習すれば分かります。
1. 2 つの Web ページを自由に作成します
1 つのポートは 2698 で、もう 1 つは 2701 です。定義上、これらは異なるソースからのものです。
2. jQuery を使用してさまざまなソースからのリクエストを開始します
ポート 2698 上の Web ページにボタンを追加すると、Click イベントによってポート 2701 を使用してドメインへの 2 つのリクエストが開始されます。
$("#getOtherDomainThings").click(function () {
$.get("http://localhost:2701/Scripts/jquery-1.4.4.min.js", function (data) {
console.log(データ)
})
$.get("http://localhost:2701/home/index", function (data) {
console.log(データ)
})
})
同一起源政策によれば、それは明らかに悲劇的になるでしょう。ブラウザはブロックし、リクエストをまったく開始しません。 (Access-Control-Allow-Origin では許可されていません)
OK、jsonp がこの問題を解決することがわかりました。
スクリプトタグのクロスドメイン機能
Microsoft の CDN などの CDN についてご存知かどうかはわかりませんが、これを使用すると、当社の Web ページで jQuery を提供する必要がなく、Microsoft の Web サイトで提供されます。
2698 ポートの Web ページに戻ると、上の Click イベントで 2701 ポート ドメインの jQuery ファイルに対するリクエストがあり、今回はリクエストに script タグを使用しています。
もちろん、200でOK
ポート 2698 を持つ同じ Web ページが 2701 ドメインへのリクエストを開始する場合、スクリプト内で scr 属性を設定するのは問題ありませんが、その逆の場合は悲惨です。スクリプトのクロスドメイン機能を利用する、これが jsonp の基礎です。
スクリプトを使用してさまざまなソースから json を取得します
jsonp と呼ばれているので、目的はやはり json であり、ドメインを越えて取得されることは明らかです。上記の分析に基づいて、js を使用して script タグを構築し、json URL をスクリプトの scr 属性に割り当て、スクリプトを dom に挿入し、ブラウザーに取得させることが簡単に考えられます。練習:
function CreateScript(src) {
$("<script><//script>").attr("src", src).appendTo("body")<br>
}<br>
</div>
<br>
ボタン イベントを追加してテストします: <br>
<div class="codetitle">
<span><a style="CURSOR: pointer" data="4331" class="copybut" id="copybut4331" onclick="doCopy('code4331')"><u>コードをコピー</u></a></span> コードは次のとおりです:</div>
<div class="codebody" id="code4331">
<br>
$("#getOtherDomainJson").click(function () {<br>
$.get('http://localhost:2701/home/somejson', function (data) {<br>
console.log(データ)<br>
})<br>
})<br>
</div>
<p><img src="http://files.jb51.net/file_images/article/201506/20156190709927.png?2015519722" alt=""></p>
<p>まず、最初のブラウザでは、URL http://localhost:2701/home/somejson には json があり、Web ページの script タグを使用して 2698 Web ページで URL をリクエストすることも 200 OK です。ただし、下部に js 構文エラーが報告されます。 script タグでロードした後、応答は js としてすぐに実行されることがわかります。明らかに、{"Email":"zhww@outlook.com","Remark":"I from the far east"} は、法的なjsステートメント。 </p>
<p>スクリプトを使用して外部 jsonp を取得します</p>
<p>明らかに、上記の json をコールバック メソッドに入れるのが最も簡単な方法です。たとえば、次のようになります: </p>
<p><img src="http://files.jb51.net/file_images/article/201506/20156190730417.png?2015519738" alt=""></p>
<p>jsonpcallback メソッドが存在する場合、jsonpcallback({"Email":"zhww@outlook.com","Remark":"I from the far east"}) は正当な JS ステートメントです。 </p>
<p>サーバーはクライアントのコールバックが何であるかを知らないため、それを jsonpcallback にハードコーディングすることは不可能です。そのため、クライアントにコールバック メソッドが何であるかをサーバーに伝えるために QueryString をもたらします。もちろん、QueryString のキーです。上記のように、サーバーの合意に従う必要があります。これは「コールバック」です。 </p>
<p>コールバック関数の追加: <br>
</p>
<div class="codetitle">
<span><a style="CURSOR: pointer" data="86577" class="copybut" id="copybut86577" onclick="doCopy('code86577')"><u>コードをコピー</u></a></span> コードは次のとおりです:</div>
<div class="codebody" id="code86577">
<br>
function jsonpcallback(json) {<br>
console.log(json)<br>
}<br>
</div>
<br>
前のメソッドのパラメータを少し変更します: <br>
<div class="codetitle">
<span><a style="CURSOR: pointer" data="13280" class="copybut" id="copybut13280" onclick="doCopy('code13280')"><u>コードをコピー</u></a></span> コードは次のとおりです:</div>
<div class="codebody" id="code13280">
<br>
$("#getJsonpByHand").click(function () {<br>
CreateScript("http://localhost:2701/home/somejsonp?callback=jsonpcallback")<br>
})<br>
</div>
<p><img src="http://files.jb51.net/file_images/article/201506/20156190749818.png?2015519756" alt=""></p>
<p>200OK、サーバーは jsonpcallback({"Email":"zhww@outlook.com","Remark":"私は極東から来ました"}) を返します。もちろん、これは次のようになります。実行されました。 OK、jsonを正常に取得しました。そうです、これはすべて jsonp に関するものです。 </p>
<p><strong>jQuery を使用して jsonp を取得します</strong><br>
上記の方法では、script タグを挿入してコールバックを定義する必要がありますが、少し面倒ですが、上記の jsonp: <br> と同様に、jQuery を使用して目的の json データを直接取得できます。
</p>
<div class="codetitle">
<span><a style="CURSOR: pointer" data="33170" class="copybut" id="copybut33170" onclick="doCopy('code33170')"><u>コードをコピー</u></a></span> コードは次のとおりです:</div>
<div class="codebody" id="code33170">
<br>
$("#getJsonpByJquery").click(function () {<br>
$.ajax({<br>
URL: 'http://localhost:2701/home/somejsonp',<br>
データ型: "jsonp",<br>
jsonp: "コールバック",<br>
成功: 関数 (データ) {<br>
console.log(データ)<br>
}<br>
})<br>
})<br>
</div>
<br>
得られる結果は上記と同様です。
<p><strong>概要</strong></p>
<p>スクリプト タグを使用して、次のように同一生成元ポリシーをバイパスしてデータを取得できます。 jsonpcallback はページ上に存在するコールバック メソッドで、パラメーターは目的の json です。 <br>
</p>
<div class="codetitle">
<span><a style="CURSOR: pointer" data="58" class="copybut" id="copybut58" onclick="doCopy('code58')"><u>コードをコピー</u></a></span> コードは次のとおりです:</div>
<div class="codebody" id="code58">
<br>
jsonpcallback({"メール":"zhww@outlook.com","備考":"私は極東から来ました"})<br>
</div>
<p>ネイティブ js を追加:<br>
</p>
<div class="codetitle">
<span><a style="CURSOR: pointer" data="99395" class="copybut" id="copybut99395" onclick="doCopy('code99395')"><u>コードをコピー</u></a></span> コードは次のとおりです:</div>
<div class="codebody" id="code99395">
<br>
<button id="btn">クリック</button><br>
<スクリプトタイプ="text/javascript"><br>
関数 $(str){<br>
document.getElementById(str)<br>を返す
}<br>
function CreateScript(src) {<br>
var Scrip=document.createElement('script');<br>
Scrip.src=src;<br>
document.body.appendChild(Scrip);<br>
}<br>
function jsonpcallback(json) {<br>
console.log(json);//Object { email="中国", email2="中国222"}<br>
}<br>
$('btn').onclick=function(){<br>
CreateScript("http://localhost:51335/somejson?callback=jsonpcallback") <br>
}<br>
</script>