Question

JavaScript

Par exemple, j'ai le code JavaScript suivant (Dojo 1.6 est déjà chargé):

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);
}

requête directe du navigateur

Je comprends que mon serveur recevra la requête comme si je tapais ce qui suit dans la barre d'adresse:

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

Réponse attendue

Si je directement interrogé mon serveur en utilisant la barre d'adresse du navigateur, je vais recevoir, dans le type MIME application/json et rendu dans le navigateur texte brut, quelque chose comme ceci:

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

Problème

Maintenant, en regardant en arrière à la partie II du JavaScript, je voudrais exécuter la demande JSONP avec dojo.io.script.get(jsonpArgs). Cela retourne un objet Deferred, que je peux profiter de .then en enchaînant après. On notera que le gestionnaire I définie pour l'événement .then de sortie qui a capturé data à la console.

Cependant, tout ce que je reçois dans la console est un Event. J'ai essayé de chercher son arbre de données, mais je ne pouvais pas trouver les données que je m'y attendais.

Question

  1. Où est la réponse à une demande JSONP stockée? Comment puis-je trouver?
  2. Mon serveur (qui contrôle I) ne fournit qu'un rendu de texte brut des données demandées, enveloppé dans la fonction callback (ici spécifié comme recover), et spécifie un type MIME application/json. Y at-il autre chose que je dois installer sur mon serveur, de sorte que les données de réponse est capturée par l'objet Deferred?

Solution Tentative

Je peux effectivement récupérer la réponse en définissant la fonction de rappel (dans ce cas recover dans la partie III du JavaScript). Cependant, dans les didacticiels Dojo, ils ont juste récupéré les données en utilisant le cadre Deferred (et .then). Comment puis-je le faire en utilisant Deferreds Dojo?

Mise à jour (en utilisant l'exemple Twitter du tutoriel Dojo)

Prenons par exemple ce script du tutoriel Dojo, Obtenir Jiggy Avec JSONP . J'édita pour enregistrer les données sur la console.

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;
});

Pour console.log(data), je reçois un Object, pas Event comme illustré par mon cas. Comme l'exemple implique que les données réside dans data.results, j'essaie aussi de parcourir cet arbre, mais je ne vois pas mes données attendues de Twitter. Je suis à une perte.

Pour console.log(data.results), je reçois un tableau de Objects. Si je fais une recherche directement nous Twitter, voici ce que je reçois en texte clair. Chaque Object contient les méta-données tweet comme d'habitude le nom d'utilisateur, le temps, le portrait de l'utilisateur et le tweet lui-même. Assez facile.

Celui-ci me frappe à droite sur la tête. Le gestionnaire de la chaîne .then, une fonction anonyme, ne reçoit qu'une seule data d'argument. Mais pourquoi est-ce que la propriété results dans console.log(data) et l'objet retourné que je reçois de console.log(data.results) sont autre ?

Était-ce utile?

La solution

Je l'ai.

Mise en oeuvre de rappel manuel

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);

Ceci est la demande que mon serveur recevra:

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

Dans ce cas, je vais attendre la sortie suivante de mon serveur:

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

Trois choses à noter:

  1. Server attend callback dans la chaîne URL de requête. callback est mis en œuvre comme une propriété de jsonpArgs.
  2. Parce que je spécifié callback=recover, mon serveur grèvera recover( + the_data_I_need + ), retourne toute la chaîne dans le navigateur, et le navigateur exécutera recover(the_data_I_need). Ce moyen ...
  3. Que je vais devoir définir, par exemple, function recover(one_argument_only) {doAnythingYouWantWith(one_argument_only)}

Le problème avec cette approche est que je ne peux pas profiter de l'enchaînement de Deferred utilisant .then. Par exemple:

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

Cela me donnera un Event, sans trace de la réponse attendue du tout.


Profitant de la mise en œuvre de JSONP Dojo demande

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);

Ceci est la demande que mon serveur recevra:

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

Dans ce cas, je vais attendre la sortie suivante de mon serveur:

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

choses à noter:

  1. Notez la propriété de jsonpArgs, callbackParamName. La valeur de cette propriété doit être le nom de la variable (dans la chaîne URL de requête) attendu par le serveur. Si mon serveur attend callbackfoo, puis callbackParamName: "callbackfoo". Dans mon cas, mon serveur attend le nom callback, callbackParamName: "callback" donc.

  2. Dans l'exemple précédent, je spécifié dans l'URL de requête callback=recover et a procédé à la mise en œuvre function recover(...) {...}. Cette fois-ci, je ne pas besoin d'inquiéter. Dojo insère sa propre callback=some_function_name_generated_by_dojo fonction préférée.

  3. Je suppose some_function_name_generated_by_dojo à définir comme:

Définition:

function some_function_name_generated_by_dojo(response_from_server) {
    return response_from_server;
}

Bien sûr, la définition n'est pas aussi simple que cela, mais l'avantage de cette approche est que je peux profiter du cadre Différé Dojo. Voir le code ci-dessous, qui est identique à l'exemple précédent:

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

Cela me donnera les données exactes dont j'ai besoin:

{
    id: 1234,
    name: Juan,
    data: [
        ["2000-01-01", 1234],
        ["2000-01-02", 5678]
    ]
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top