【问题标题】:Is this server jsonp response is a valid one?此服务器 jsonp 响应是否有效?
【发布时间】:2012-10-28 13:05:50
【问题描述】:

我是向服务器人员发送请求的客户端人员。我的最终目标是在 jsonp 中发送请求。

这是我使用?accept=json 发送请求时得到的服务器响应(并且因为不是 jsonp 而收到无效会话错误)

{"errorCode":-15,"errorDescription":"SessionNotFoundException - Session not found","success":false,"payload":null}

我可以阅读它,它很好。

然而,这是?accept=jsonp的服务器响应:

jQuery171024326910870149732_1351429007451({"action":"", "type":"", "callerId":""}, {"errorCode":0,"errorDescription":"OK","success":true,"payload":null});

它是这两个我不知道如何阅读的对象的形式:{a},{b}

当我使用 jQuery ajax 调用时 服务器数据的输出只有{a}部分:

Object {action: "", type: "", callerId: ""}

我的 2 个问题是:

  1. 具有 2 个对象 ({a},{b}) 的服务器响应是否有效?服务员发送这种对象是错误的还是有效的?
  2. 如何读取 jsonp 对象?我似乎无法正确阅读的 ajax 调用有什么问题?

这是我使用的 ajax 调用:

$.ajax({
            url:url,
            dataType:'jsonp',
            success:function(data){
                console.log("data is,"data")
                //if the call was success
                if (data.success) {

                    //if errors
                }   else {

                }
            }
        } 

【问题讨论】:

  • 由于您要返回的是 2 个对象,因此请尝试在成功处理程序中使用 2 个对象。 success:function(data1, data2){ 让我知道这是否有效。
  • 我收到一个控制台错误“Uncaught SyntaxError: Unexpected token s”,我猜这意味着它不明白如何读取“data2”,有什么解决方案吗?也许是一种定义 data2 的方法?
  • 这是 2 个独立的有效 JSON 块,所以我认为这并不重要。您是否可以控制服务器端 JSON 响应?
  • 服务器端没有控制权。
  • 是否可以给我写一个错误和成功的有效 $.ajax jsonp 请求示例,以便我看到它的外观?我想我会使用诸如“数据”“数据类型”之类的参数,因为我不知道如何编写它们并将它记下来会为我简化它

标签: javascript jquery ajax json jsonp


【解决方案1】:

为了实际验证成功回调不能处理 2 个参数,我尝试了一个简单的测试,其中包含 2 个 arg 函数和 2 个传递给它的对象:

function test(a,b) {
    console.info(a);
}

test({"name":"test"},{"hello":"world"});

这成功了,因为我在 JavaScript 对象表示法中将两个单独的对象传递给了一个需要 2 个参数的函数。

接下来,我用一个简单的 PHP 脚本重新创建了一个示例响应:

<?php echo $_REQUEST["callback"]?>({"test":"test"},{"hello":"world"});

所以,下一步,我继续修改成功回调,使其接受 2 个参数:

$.ajax({
            url:'http://local.sandbox.com/jsonp2/test.php',
            dataType:'jsonp',
            success:function(data, data2){
                console.log("data is " + data2)
                //if the call was success
                if(data.success) {
                   alert("yes");
                    //if errors
                }   else {
                    alert(data2.hello);
                }
            }
        }); 

现在,根据jQuery AJAX Success Handler docs,这是我遇到问题的地方:

成功(数据,文本状态,jqXHR)

Function, Array 要成为的函数 如果请求成功则调用。函数通过了三个 论据:

  • 从服务器返回的数据,格式按照 数据类型参数;
  • 描述状态的字符串;
  • 和 jqXHR (在 jQuery 1.4.x 中,XMLHttpRequest)对象。

从 jQuery 1.5 开始, 成功设置可以接受一个函数数组。每个功能都会 被依次调用。这是一个 Ajax 事件。

  • 重点是我的

成功处理程序的第二个参数是 always 将是响应的状态,所以我在控制台中的输出是“数据成功”,而 else 块中的警报未定义.

jQuery 的 jsonp 实现无疑是为处理回调中的单个对象而设计的,因为它替换了回调查询参数的自定义值,服务器将其用作“填充”或响应的包装器,通常形式为“jQuery1232432423432432”。根据文档,成功处理程序接受 3 个参数,其中第一个是对象,最后两个由 jQuery 提供。填充函数只需要 1 个参数。因此,jQuery 无法解决这个问题。

但是,有一种技术仍然可以利用现有的服务器端响应,假设您无法控制服务器生成的内容。


解决方案:使用 Script Tag Remoting,不使用 jQuery:

// this is a custom function to make jsonp requests to the server.
function jsonp(url, callback) {
    var script = document.createElement("script");
    script.setAttribute("type","text/javascript");
    script.setAttribute("src", url + "?callback="+callback + "&cachebuster="+new Date().getTime());
    document.getElementsByTagName("head")[0].appendChild(script);
}

要调用该函数,请使用它来代替 $.ajax 调用,但传入一个命名的回调处理程序除外:

jsonp(url, "myCustomSuccessFunction");

确保您定义了一个自定义的命名成功回调函数:

function myCustomSuccessFunction(data1, data2) {
    console.info(data1);  // contains first object
    console.info(data2);  // contains second object

    // do stuff w/said objects here

}

【讨论】:

  • 非常感谢您的回复。我正在测试它以查看它是否有效(到目前为止它不起作用,但我想这是我在代码上做的错误)
  • 在您的测试中,您确实将类型设置为 jsonp 这可能会影响处理程序的签名,因为在插入脚本标记而不是请求时,两者都不(容易)可用。 Jsonp 调用实际上并不请求任何东西,只是简单地插入一个标签,让浏览器处理其余的事情
  • @RuneFS,我假设您指的是 dataType。如果不是jsonp,则跨域请求失败。如果是,则失败,因为来自服务器的响应包含 2 个对象,而不是 1 个,并且成功处理程序期望 1 个单个 JSON 对象,而其他 2 个参数期望接收元数据。
  • @Alon,关键是你必须确保你定义了“myCustomSuccessHandler”。另外,有一个错字,我会更新以修复它。 jsonp 命令应如下所示:jsonp(url, "myCustomSuccessFunction");。回调必须用引号引起来。
  • 当我执行脚本时,我在控制台中收到错误:400(错误请求)此链接:muki.foo.bar.com/something//api/1234/…。它是否因交叉浏览问题而失败? (因为我从 foo.bar 向 muki.foo.bar 发送了一个请求)?
猜你喜欢
  • 2013-12-20
  • 2023-04-11
  • 2011-12-14
  • 2011-03-18
  • 2016-10-25
  • 2011-09-24
  • 2013-04-06
  • 2011-02-25
  • 2019-10-04
相关资源
最近更新 更多