例如,我有以下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]
]
}
);
现在,回顾一下JavaScript的第二部分,我将用dojo.io.script.get(jsonpArgs)
执行JSONP请求。这将返回一个Deferred
对象,我可以通过在其后面链接.then
来利用它。请注意,我为.then
事件定义了处理程序,以将捕获的data
输出到控制台。
但是,我在控制台中获得的只是Event
。我试图搜索它的数据树,但我找不到我预期的数据。
callback
函数(此处指定为recover
)中,并指定application/json
MIME类型。我需要在服务器上设置其他任何内容,以便Deferred
对象捕获响应数据吗?我实际上可以通过定义回调函数来恢复响应(在本例中,在JavaScript的第三部分中为recover
)。但是,在Dojo教程中,他们只是使用Deferred
(和.then
)框架恢复了数据。如何使用Dojo Deferred
s?
以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)
,我得到的是Object
,而不是Event
,如我的情况所示。由于该示例意味着数据驻留在data.results
中,我还尝试浏览此树,但我没有看到来自Twitter的预期数据。我很茫然。
对于console.log(data.results)
,我得到一个Object
的数组。如果我直接查询Twitter,这就是我用明文得到的。每个Object
都包含通常的推文元数据,如用户名,时间,用户肖像和推文本身。很容易。
这个击中了我的头部。 .then
链的处理程序(匿名函数)只接收一个参数data
。但为什么results
和 console.log(data)
属性console.log(data.results)
从{{1}}得到的不同?
答案 0 :(得分: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]
]
});
需要注意三点:
callback
。 callback
已作为jsonpArgs
。callback=recover
,我的服务器将附加recover(
+ the_data_I_need
+ )
,将整个字符串返回给浏览器,浏览器将执行{{1} }。这意味着...... 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
这是我的服务器将收到的请求:
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
的属性。此属性的值必须是服务器期望的变量(在查询URL字符串中)的名称。如果我的服务器需要callbackParamName
,那么callbackfoo
。在我的情况下,我的服务器需要名称callbackParamName: "callbackfoo"
,因此callback
。
在上一个示例中,我在查询网址callbackParamName: "callback"
中指定并继续实施callback=recover
。这次,我不需要担心。 Dojo将插入自己的首选函数function recover(...) {...}
。
我认为callback=some_function_name_generated_by_dojo
被定义为:
定义:
some_function_name_generated_by_dojo
当然,定义并不那么简单,但这种方法的优点是我可以利用Dojo的Deferred框架。请参阅下面的代码,它与前面的示例相同:
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);
})