Dove viene memorizzata la risposta dopo una richiesta di Dojo JSONP?
Domanda
JavaScript
Ad esempio, ho il seguente codice JavaScript (DOJO 1.6 è già caricato):
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);
}
Domanda diretta dal browser
Capisco che il mio server riceverà la query come se avessi digitato quanto segue nella barra degli indirizzi:
http://myapp.appspot.com/query?id=1234&name=Juan&start_date=2000-01-01&callback=recover
Risposta prevista
Se ho interrogato direttamente il mio server usando la barra degli indirizzi del browser, riceverò, in tipo mime application/json
E il testo in chiaro reso nel browser, qualcosa del genere:
recover(
{
id: 1234,
name: Juan,
data: [
["2000-01-01", 1234],
["2000-01-02", 5678]
]
}
);
Problema
Ora, guardando indietro alla parte II del JavaScript, eseguirei la richiesta JSONP con dojo.io.script.get(jsonpArgs)
. Questo restituisce a Deferred
Oggetto, di cui posso trarre vantaggio concatando .then
dopo ciò. Nota che ho definito il gestore per il .then
evento da output che catturato data
alla console.
Tuttavia, tutto ciò che ottengo nella console è un Event
. Ho provato a cercare il suo albero di dati, ma non sono riuscito a trovare i dati che mi aspettavo.
Domanda
- Dov'è la risposta per una richiesta JSONP memorizzata? Come lo trovo?
- Il mio server (che controllo) emette solo un rendering in chiaro dei dati richiesti, avvolto in
callback
funzione (qui specificato comerecover
) e specifica aapplication/json
Tipo di mimo. C'è qualcos'altro che devo impostare sul mio server, in modo che i dati di risposta vengano acquisiti dalDeferred
oggetto?
Soluzione tentata
Posso effettivamente recuperare la risposta definendo la funzione di callback (in questo caso recover
Nella parte III del Javascript). Tuttavia, nei tutorial Dojo, hanno appena recuperato i dati utilizzando il Deferred
(e .then
) struttura. Come lo faccio usando dojo Deferred
S?
Aggiornamento (utilizzando l'esempio di Twitter da Dojo Tutorial)
Prendi ad esempio questo script dal tutorial Dojo, Ottenere Jiggy con JSONP. L'ho modificato per registrare i dati alla 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;
});
Per console.log(data)
, Ottengo un Object
, non un Event
come illustrato dal mio caso. Poiché l'esempio implica che i dati risiedono in data.results
, Provo anche a sfogliare questo albero, ma non vedo i miei dati previsti da Twitter. Sono in perdita.
Per console.log(data.results)
, Ricevo una serie di Object
S. Se chiedo direttamente Twitter, questo è ciò che otterrei in chiaro. A testa Object
Contiene i soliti metadati tweet come nome utente, tempo, ritratto utente e tweet stesso. Abbastanza facile.
Questo mi colpisce proprio sulla testa. Il gestore per il .then
La catena, una funzione anonima, riceve solo un argomento data
. Ma perché è il results
Proprietà in console.log(data)
e l'oggetto restituito che ottengo da console.log(data.results)
sono diverso?
Soluzione
Capito.
Implementazione del callback manuale
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);
Questa è la richiesta che il mio server riceverà:
http://myapp.appspot.com/query?id=1234&name=Juan&start_date=2000-01-01&callback=recover
In questo caso, mi aspetto il seguente output dal mio server:
recover({
id: 1234,
name: Juan,
data: [
["2000-01-01", 1234],
["2000-01-02", 5678]
]
});
Tre cose da notare:
- Il server si aspetterà
callback
Nella stringa URL di query.callback
è implementato come proprietà dijsonpArgs
. - Perché ho specificato
callback=recover
, il mio server si alleneràrecover(
+the_data_I_need
+)
, restituisce l'intera stringa al browser e il browser eseguiràrecover(the_data_I_need)
. Questo significa... - Che dovrò definire, ad esempio,
function recover(one_argument_only) {doAnythingYouWantWith(one_argument_only)}
Il problema con questo approccio è che non posso trarne vantaggio Deferred
concatenamento dell'uso .then
. Per esempio:
dojo.io.script.get(jsonpArgs).then(function(response_from_server) {
console.log(response_from_server);
})
Questo mi darà un Event
, senza alcuna traccia della risposta prevista.
Sfruttare l'implementazione di Dojo delle richieste 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);
Questa è la richiesta che il mio server riceverà:
http://myapp.appspot.com/query?id=1234&name=Juan&start_date=2000-01-01&callback=some_function_name_generated_by_dojo
In questo caso, mi aspetto il seguente output dal mio server:
some_function_name_generated_by_dojo({
id: 1234,
name: Juan,
data: [
["2000-01-01", 1234],
["2000-01-02", 5678]
]
});
Cose da notare:
Notare la proprietà di
jsonpArgs
,callbackParamName
. Il valore di questa proprietà deve essere il nome della variabile (nella stringa URL di query) prevista dal server. Se il mio server si aspettacallbackfoo
, poicallbackParamName: "callbackfoo"
. Nel mio caso, il mio server si aspetta il nomecallback
, dunquecallbackParamName: "callback"
.Nell'esempio precedente, ho specificato nell'URL di query
callback=recover
e procedette ad attuarefunction recover(...) {...}
. Questa volta, non ho bisogno di preoccuparmi. Dojo inserirà la propria funzione preferitacallback=some_function_name_generated_by_dojo
.immagino
some_function_name_generated_by_dojo
da definire come:
Definizione:
function some_function_name_generated_by_dojo(response_from_server) {
return response_from_server;
}
Naturalmente la definizione non è così semplice, ma il vantaggio di questo approccio è che posso trarre vantaggio dal framework differito di Dojo. Vedi il codice seguente, che è identico all'esempio precedente:
dojo.io.script.get(jsonpArgs).then(function(response_from_server) {
console.log(response_from_server);
})
Questo mi darà i dati esatti di cui ho bisogno:
{
id: 1234,
name: Juan,
data: [
["2000-01-01", 1234],
["2000-01-02", 5678]
]
}