Где ответ хранится после запроса Dojo JSONP?
Вопрос
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
Ожидаемый ответ
Если я прямо запрошу свой сервер с помощью адресной панели браузера, я получу, в типе Mime application/json
и открытый текст, отображаемый в браузере, что -то вроде этого:
recover(
{
id: 1234,
name: Juan,
data: [
["2000-01-01", 1234],
["2000-01-02", 5678]
]
}
);
Проблема
Теперь, оглядываясь на часть II JavaScript, я бы выполнил запрос JSONP с dojo.io.script.get(jsonpArgs)
. Анкет Это возвращает а Deferred
объект, которым я могу воспользоваться цепочкой .then
после этого. Обратите внимание, что я определил обработчик для .then
событие для вывода, которые захватили data
к консоли.
Однако все, что я получаю в консоли, это Event
. Анкет Я попытался найти его дерево данных, но я не смог найти ожидаемые данные.
Вопрос
- Где хранится ответ на запрос JSONP? Как мне это найти?
- Мой сервер (который я управляю) только выводит только открытый рендеринг запрошенных данных, завернутый в
callback
функция (здесь указано какrecover
) и указываетapplication/json
Тип мима. Есть ли что -нибудь еще, что мне нужно настроить на моем сервере, чтобы данные ответа были полученыDeferred
объект?
Попытка решения
Я действительно могу восстановить ответ, определив функцию обратного вызова (в этом случае recover
В части III JavaScript). Однако в учебных пособиях Dojo они просто восстановили данные, используя Deferred
(а также .then
) рамки. Как сделать это с помощью додзё Deferred
s?
Обновление (используя пример Twitter из учебника Dojo)
Взять, к примеру, этот сценарий из учебника Dojo, Получение JIGGY с 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)
, Я получаю Object
, не Event
Как показано в моем случае. Поскольку пример подразумевает, что данные находятся в data.results
, Я также пытаюсь просмотреть это дерево, но я не вижу своих ожидаемых данных из Twitter. Я в растерянности.
За console.log(data.results)
, Я получаю множество Object
с Если я запрошут Twitter напрямую, это то, что я бы получил в явном тексту. Каждый Object
Содержит обычные метадаты твита, такие как имя пользователя, время, портрет пользователя и сам твит. Достаточно просто.
Этот удар мне ударяет прямо по голове. Обработчик для .then
Цепочка, анонимная функция, получает только один аргумент data
. Анкет Но почему это то, что results
собственность в console.log(data)
а также возвращенный объект, от которого я получаю console.log(data.results)
находятся другой?
Решение
Я понял.
Ручная реализация обратного вызова
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]
]
});
Три вещи следует отметить:
- Сервер будет ожидать
callback
В строке URL -адреса запроса.callback
реализуется как собственностьjsonpArgs
. - Потому что я указал
callback=recover
, мой сервер подключитrecover(
+the_data_I_need
+)
, возвращает всю строку в браузер, а браузер выполнитrecover(the_data_I_need)
. Анкет Это означает... - Что мне придется определить, например,
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
, без следа ожидаемого ответа вообще.
Использование внедрения запросов JSONP Dojo
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]
]
});
Что следует отметить:
Обратите внимание на собственность
jsonpArgs
,callbackParamName
. Анкет Значение этого свойства должно быть именем переменной (в строке URL -адреса запроса), ожидаемой сервером. Если мой сервер ожидаетcallbackfoo
, тогдаcallbackParamName: "callbackfoo"
. Анкет В моем случае мой сервер ожидает имяcallback
, следовательноcallbackParamName: "callback"
.В предыдущем примере я указал в URL -адресе запроса
callback=recover
и приступил к реализацииfunction recover(...) {...}
. Анкет На этот раз мне не нужно беспокоиться об этом. Dojo вставит свою собственную предпочтительную функциюcallback=some_function_name_generated_by_dojo
.Я полагаю
some_function_name_generated_by_dojo
быть определенным как:
Определение:
function some_function_name_generated_by_dojo(response_from_server) {
return response_from_server;
}
Конечно, определение не так просто, но преимущество этого подхода в том, что я могу воспользоваться отсроченной структурой Додзё. См. Код ниже, который идентичен предыдущему примеру:
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]
]
}