D'où la réponse sont stockés après une demande Dojo JSONP?
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
- Où est la réponse à une demande JSONP stockée? Comment puis-je trouver?
- 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é commerecover
), et spécifie un type MIMEapplication/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'objetDeferred
?
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 Deferred
s 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 Object
s. 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 ?
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:
- Server attend
callback
dans la chaîne URL de requête.callback
est mis en œuvre comme une propriété dejsonpArgs
. - Parce que je spécifié
callback=recover
, mon serveur grèverarecover(
+the_data_I_need
+)
, retourne toute la chaîne dans le navigateur, et le navigateur exécuterarecover(the_data_I_need)
. Ce moyen ... - 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:
-
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 attendcallbackfoo
, puiscallbackParamName: "callbackfoo"
. Dans mon cas, mon serveur attend le nomcallback
,callbackParamName: "callback"
donc. -
Dans l'exemple précédent, je spécifié dans l'URL de requête
callback=recover
et a procédé à la mise en œuvrefunction recover(...) {...}
. Cette fois-ci, je ne pas besoin d'inquiéter. Dojo insère sa proprecallback=some_function_name_generated_by_dojo
fonction préférée. -
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]
]
}