4

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

预期响应

如果我直接使用浏览器地址栏查询我的服务器,我将收到,application/json在浏览器中呈现的 MIME 类型和纯文本,如下所示:

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

问题

现在,回顾 JavaScript 的第二部分,我将使用dojo.io.script.get(jsonpArgs). 这会返回一个Deferred对象,我可以通过链接它来利用.then它。请注意,我为.then事件定义了处理程序,以将捕获的内容输出data到控制台。

但是,我在控制台中得到的只是一个Event. 我试图搜索它的数据树,但我找不到我期望的数据。

问题

  1. JSONP 请求的响应存储在哪里?我如何找到它?
  2. 我的服务器(由我控制)仅输出请求数据的明文呈现,包装在callback函数中(此处指定为recover),并指定application/jsonMIME 类型。我还需要在我的服务器上设置什么,以便Deferred对象捕获响应数据吗?

尝试的解决方案

我实际上可以通过定义回调函数来恢复响应(在这种情况下recover,在 JavaScript 的第三部分)。但是,在 Dojo 教程中,他们只是使用Deferred(and .then) 框架恢复了数据。我如何使用 Dojo 来做到这一点Deferred

更新(使用 Dojo 教程中的 Twitter 示例)

以 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),我得到一个 s 数组Object。如果我直接查询 Twitter,这就是我得到的明文。每个都Object包含通常的推文元数据,如用户名、时间、用户画像和推文本身。很容易。

这一击正中我的头。链的处理程序.then,一个匿名函数,只接收一个参数data。但是为什么我从中得到的属性和返回的results对象console.log(data) 不同console.log(data.results)

4

1 回答 1

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

需要注意的三点:

  1. 服务器将期望callback在查询 URL 字符串中。callback被实现为 的属性jsonpArgs
  2. 因为我指定callback=recover了,我的服务器会附加recover(++ ,将整个字符串返回给浏​​览器,浏览器会the_data_I_need执行. 这表示...)recover(the_data_I_need)
  3. 我必须定义,例如,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,完全没有预期响应的痕迹。


利用 Dojo 的 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);

这是我的服务器将收到的请求:

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

注意事项:

  1. jsonpArgs注意,的性质callbackParamName。此属性的值必须是服务器期望的变量名称(在查询 URL 字符串中)。如果我的服务器期望callbackfoo,那么callbackParamName: "callbackfoo"。就我而言,我的服务器需要名称callback,因此callbackParamName: "callback".

  2. 在前面的示例中,我在查询 URL 中指定callback=recover并继续实现function recover(...) {...}. 这一次,我不需要担心。Dojo 将插入自己喜欢的功能callback=some_function_name_generated_by_dojo

  3. 我想some_function_name_generated_by_dojo被定义为:

定义:

function some_function_name_generated_by_dojo(response_from_server) {
    return response_from_server;
}

当然定义没那么简单,但是这种方式的好处是我可以利用Dojo的Deferred框架。请参阅下面的代码,它与前面的示例相同:

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]
    ]
}
于 2012-01-13T10:53:10.937 回答