8

すべて同じ jsonpCallback 関数を使用して複数の jsonp リクエストを実行すると、jQuery で問題が発生します。コールバック関数がトリガーされるのは、そのうちの1つだけのようです。JSONP リクエストは何らかの形で互いに上書きしていますか?

github に対して 2 つの jsonp リクエストを実行する例の下で、両方の firebug がそれらの両方が返されることを示していても、コールバック関数getNameはそれらの 1 つに対してのみ呼び出されます。

function getName(response){
    alert(response.data.name);
}

function userinfo(username){
    $.ajax({
        url: "https://api.github.com/users/" + username,
        jsonpCallback: 'getName',
        dataType: "jsonp"
    });        
}

users = ["torvalds", "twitter", "jquery"]
for(var i = 0; i < users.length; i++){
  userinfo(users[i]);
}
4

4 に答える 4

20

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 つの理由から機能しなくなります。

  1. something.js をロードするたびに、同じ loadJson() コールバックが呼び出されます。どのリクエストがどのリプライに対応するかを知る方法はありません。

  2. キャッシング - 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=joejoe({...

キャッシング

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) { ... }
});
于 2012-05-04T02:59:14.597 に答える
3

代わりに成功コールバックを使用してください。

function userinfo(username){
    $.ajax({
        url: "https://api.github.com/users/" + username,
        success: getName,
        dataType: "jsonp"
    });        
}
于 2012-04-23T23:12:51.120 に答える
1
$(function() {
    function userinfo(username){
      var XHR = $.ajax({
             url: "https://api.github.com/users/" + username,
             dataType: "jsonp"
         }).done(function(data) {
             console.log(data.data.name);
         });
    }

    users = ["torvalds", "twitter", "jquery"];
    for(var i = 0; i < users.length; i++){
       userinfo(users[i]);
    }
});  ​
于 2012-04-23T23:28:41.620 に答える
0

確かではありませんが、github API へのその呼び出しから得た応答にはgravatar_id.

これは私のために働いた:

function getGravatar(response){
    var link = response.data.avatar_url;
    $('#list').append('<div><img src="' + link + '"></div>');
}
于 2012-04-23T23:19:44.993 に答える