jsonp の仕組みにより、リクエストは 1 回しか実行されませんでした。
Jsonp とは、外部ドメインからページにスクリプト タグを追加して、最新のブラウザー (および 2011 年 4 月現在の IE6 および 7) に組み込まれているクロスサイト スクリプティング保護を回避することを意味します。そのスクリプトがページ上の残りのスクリプトと対話するようにするには、読み込まれるスクリプトがページ上の関数を呼び出す必要があります。その関数はグローバル名前空間に存在する必要があります。つまり、その名前の関数は 1 つしか存在できません。つまり、JQuery がなければ、単一の jsonp リクエストは次のようになります。
<script>
function loadJson(json) {
// Read the json
}
</script>
<script src="//outsidedomain.com/something.js"></script>
something.js は次のようになります。
loadJson({name:'Joe'})
この場合の something.js には、保持する JSON をロードするためのハードコーディングされたコールバックがあり、ページには、このようなスクリプトがロードされて呼び出されるのを待機するハードコーディングされた loadJson 関数があります。
ここで、複数のソースから json をロードし、それぞれがいつ終了するかを通知できるようにしたい、または同じソースから JSON を複数回ロードして、各呼び出しがいつ終了したかを通知できるようにしたいとします。後で電話した後。このハードコーディングされたアプローチは、次の 2 つの理由から機能しなくなります。
something.js をロードするたびに、同じ loadJson() コールバックが呼び出されます。どのリクエストがどのリプライに対応するかを知る方法はありません。
キャッシング - something.js を 1 回ロードすると、ブラウザーはサーバーにそれを再度要求することはありません。キャッシュから戻すだけで、計画が台無しになります。
毎回異なる方法で JSON をラップするようにサーバーに指示することで、これらの両方を解決できます。簡単な方法は、その情報を のようなクエリ文字列パラメーターで渡すこと?callback=loadJson12345
です。あなたのページは次のように見えます:
<script>
function loadJson1(json) {
// Read the json
}
function loadJson2(json) {
// Read the json
}
</script>
<script src="//outsidedomain.com/something.js?callback=loadJson1"></script>
<script src="//outsidedomain.com/somethingelse.js?callback=loadJson2"></script>
JQuery では、これはすべて抽象化されており、$.ajax への通常の呼び出しのように見えます。つまり、success 関数が起動することを期待しています。jsonp のロードごとに適切な成功関数が確実に起動されるようにするために、JQuery は、JQuery1233432432432432 のようなグローバル名前空間に長いランダムなコールバック関数名を作成し、それをクエリ文字列のコールバック パラメータとして渡し、スクリプトがロードされるのを待ちます。すべてが正常に機能する場合、ロードするスクリプトは JQuery が要求したコールバック関数を呼び出し、$.ajax 呼び出しから成功ハンドラーを起動します。
「正しく機能する」には、サーバー側がクエリ文字列パラメーターを読み取り、それを->?callback
のように応答に含める必要があることに注意してください。静的ファイルであるか、サーバーがこのように再生しない場合は、ファイルをキャッシュ可能として扱う必要がある可能性があります - 以下を参照してください。?callback=joe
joe({...
キャッシング
json をキャッシュしたい場合は、cache: true を設定し、jsonpCallback プロパティを、キャッシュ可能な json ファイルにハードコーディングされた文字列に設定することで、JQuery を最初の例に近づけることができます。たとえば、この静的 json:
loadJoe({name:'Joe'})
次のように JQuery にロードしてキャッシュできます。
$.ajax({
url: '//outsidedomain.com/loadjoe.js',
dataType: 'jsonp',
cache: true,
jsonpCallback: 'loadJoe',
success: function(json) { ... }
});