4

JavaScript

たとえば、次の JavaScript コードがあります (Dojo 1.6 は既にロードされています)。

dojo.require("dojo.io.script")

// PART I
var jsonpArgs = {
    url: "http://myapp.appspot.com/query",
    content: {
        id: "1234",
        name: "Juan",
        start_date: "2000-01-01",
        callback: "recover"
    }
};

// PART II
dojo.io.script.get(jsonpArgs).then(function(data) {
    console.log(data);
});

// PART III
function recover(data) {
    console.log(data);
}

ブラウザからの直接クエリ

アドレス バーに次のように入力したかのように、サーバーがクエリを受信することを理解しています。

http://myapp.appspot.com/query?id=1234&name=Juan&start_date=2000-01-01&callback=recover

期待される反応

ブラウザーのアドレス バーを使用してサーバーに直接クエリを実行すると、application/jsonブラウザーでレンダリングされた MIME タイプとプレーンテキストで、次のようなメッセージが表示されます。

recover(
    {
        id: 1234,
        name: Juan,
        data: [
            ["2000-01-01", 1234],
            ["2000-01-02", 5678]
        ]
    }
);

問題

さて、JavaScript のパート II を振り返ると、JSONP リクエストをdojo.io.script.get(jsonpArgs). これはオブジェクトを返します。このオブジェクトは、その後にDeferredチェーンすることで利用できます.then。イベントのハンドラーを定義して.then、キャプチャーdataしたものをコンソールに出力することに注意してください。

ただし、コンソールに表示されるのはEvent. そのデータ ツリーを検索しようとしましたが、期待したデータが見つかりませんでした。

質問

  1. JSONP リクエストのレスポンスはどこに保存されますか? どうすれば見つけられますか?
  2. 私のサーバー (私が管理) は、要求されたデータのプレーンテキスト レンダリングのみを出力し、callback関数 (ここでは として指定) でラップし、 MIME タイプrecoverを指定します。application/json応答データがオブジェクトによってキャプチャされるように、サーバーに設定する必要があるものは他にありDeferredますか?

試みられた解決策

コールバック関数を定義することで、実際に応答を回復できます (この場合recoverは、JavaScript のパート III にあります)。ただし、Dojo チュートリアルでは、Deferred(および.then) フレームワークを使用してデータを復元しただけです。Dojo を使用してどのように行うDeferredのですか?

更新 (Dojo チュートリアルの Twitter の例を使用)

たとえば、Dojo チュートリアルGetting Jiggy With JSONPのこのスクリプトを取り上げます。データをコンソールに記録するように編集しました。

dojo.require("dojo.io.script");
dojo.io.script.get({
    url: "http://search.twitter.com/search.json",
    callbackParamName: "callback",
    content: {q: "#dojo"}
}).then(function(data){
    //we're only interested in data.results, so strip it off and return it
    console.log(data); // I get an Object, not an Event, but no Twitter data when browsing the results property
    console.log(data.results) // I get an array of Objects
    return data.results;
});

の場合、私のケースで示されているように ではなく、console.log(data)が得られます。この例は、データが にあることを暗示しているため、このツリーもブラウズしようとしましたが、Twitter から期待したデータが表示されません。私は途方に暮れています。ObjectEventdata.results

の場合、s のconsole.log(data.results)配列を取得しObjectます。Twitter に直接クエリを実行すると、これがプレーンテキストで取得されます。それぞれObjectには、ユーザー名、時間、ユーザーのポートレート、ツイート自体など、通常のツイート メタデータが含まれています。簡単です。

これは私の頭を直撃します。.then匿名関数であるチェーンのハンドラーは、引数を 1 つだけ受け取りますdata。しかし、resultsプロパティconsole.log(data) 返されたオブジェクトconsole.log(data.results)異なるのはなぜですか?

4

1 に答える 1

6

わかった。

手動コールバックの実装

function recover(data) {
    console.log(data);
}

var jsonpArgs = {
    url: "http://myapp.appspot.com/query",
    content: {
        id: "1234",
        name: "Juan",
        start_date: "2000-01-01",
        callback: "recover"
};

dojo.io.script.get(jsonpArgs);

これは私のサーバーが受け取るリクエストです:

http://myapp.appspot.com/query?id=1234&name=Juan&start_date=2000-01-01&callback=recover

この場合、サーバーから次の出力が期待されます。

recover({
    id: 1234,
    name: Juan,
    data: [
        ["2000-01-01", 1234],
        ["2000-01-02", 5678]
    ]
});

次の 3 つの点に注意してください。

  1. callbackサーバーは、クエリ URL 文字列を期待します。callbackのプロパティとして実装されますjsonpArgs
  2. を指定したので、サーバーは++callback=recoverを添付し、文字列全体をブラウザに返し、ブラウザは を実行します。これの意味は...recover(the_data_I_need)recover(the_data_I_need)
  3. たとえば、次のように定義する必要があります。function recover(one_argument_only) {doAnythingYouWantWith(one_argument_only)}

このアプローチの問題は、 を使用したDeferred連鎖を利用できないこと.thenです。例えば:

dojo.io.script.get(jsonpArgs).then(function(response_from_server) {
    console.log(response_from_server);
})

これEventにより、予想される応答の痕跡がまったくない が表示されます。


Dojo の JSONP 要求の実装を利用する

var jsonpArgs = {
    url: "http://myapp.appspot.com/query",
    callbackParamName: "callback",
    content: {
        id: "1234",
        name: "Juan",
        start_date: "2000-01-01"
};

dojo.io.script.get(jsonpArgs);

これは私のサーバーが受け取るリクエストです:

http://myapp.appspot.com/query?id=1234&name=Juan&start_date=2000-01-01&callback=some_function_name_generated_by_dojo

この場合、サーバーから次の出力が期待されます。

some_function_name_generated_by_dojo({
    id: 1234,
    name: Juan,
    data: [
        ["2000-01-01", 1234],
        ["2000-01-02", 5678]
    ]
});

注意事項:

  1. 、 のプロパティに注意してjsonpArgsくださいcallbackParamName。このプロパティの値は、サーバーが期待する (クエリ URL 文字列内の) 変数の名前である必要があります。サーバーが を期待している場合callbackfoocallbackParamName: "callbackfoo". 私の場合、サーバーは名前callbackを期待しているため、callbackParamName: "callback".

  2. 前の例では、クエリ URL で指定しcallback=recoverて実装に進みましたfunction recover(...) {...}。今回は、気にする必要はありません。Dojo は独自の優先機能を挿入しますcallback=some_function_name_generated_by_dojo

  3. some_function_name_generated_by_dojo次のように定義されると想像します。

意味:

function some_function_name_generated_by_dojo(response_from_server) {
    return response_from_server;
}

もちろん、定義はそれほど単純ではありませんが、このアプローチの利点は、Dojo の Deferred フレームワークを利用できることです。次のコードを参照してください。これは前の例と同じです。

dojo.io.script.get(jsonpArgs).then(function(response_from_server) {
    console.log(response_from_server);
})

これにより、必要な正確なデータが得られます。

{
    id: 1234,
    name: Juan,
    data: [
        ["2000-01-01", 1234],
        ["2000-01-02", 5678]
    ]
}
于 2012-01-13T10:53:10.937 に答える