【问题标题】:jQuery ajax jsonp calls error after successjQuery ajax jsonp调用成功后报错
【发布时间】:2013-06-18 00:49:45
【问题描述】:

我正在使用 jQuery 1.9.1 对 Etsy API 执行 jsonp。下面是一个用于调用 API 的例程;它接受一个签名的请求(url)、一个 jsonp 回调名称和一个错误处理程序。

call: function (signedOAuthRequest, callback, errorFn) {
    $.ajax({
        url: signedOAuthRequest,
        type: "GET",
        dataType: "jsonp",
        jsonpCallback: callback,
        jsonp: false,
        crossDomain: true,
        cache: true,
        processData: false,
        error: function (jqXHR, textStatus, errorThrown) {
            if (errorFn != undefined) {
                errorFn(jqXHR, textStatus, errorThrown);
            }
        }
    });

用法:

call("http://the.api/?signedrequest", "myCallback", myErrorHandler);

而且它有效。 myCallback 触发,收到的 json 对象看起来不错。一切都很好。

除了...

myCallback 完成后,错误处理程序立即运行。在错误处理程序中,状态码为 200,错误消息为"parsererror"。 errorThrown.message 是"myCallback was not called"。问题是,myCallback肯定被调用了,传递给它的 json 对象被解析得很好,所以我根本不明白。

为什么在成功调用时会引发此错误?

【问题讨论】:

  • 将回调移动到success: callback,删除jsonp: false,删除jsonpCallback,删除cache: true,也不需要type: "get"processData 也不需要。
  • 如果您想在窗口上定义自己的回调,请不要使用 jsonp 数据类型,只需使用 getScript。
  • 并传递myCallback 而不是"myCalback" 作为callback 参数
  • 你负责the.api吗?它与您的示例中运行的 JS ocde 的起源域相同吗?
  • @KevinB 该 URL 是一个预烘焙的 SHA-1 签名的 OAuth 1.0 请求(由服务器生成并传递给 JS 客户端)。它已经将回调的名称烘焙到签名中,因此如果我让 jQuery 管理回调的名称(或允许它向 URL 添加缓存时间戳),这会在提供程序上创建 OAuth 签名不匹配。跨度>

标签: json jquery cross-domain jsonp


【解决方案1】:

根据 cmets 和您的问题,这就是我编写该代码的方式:

function (signedOAuthRequest, callbackName, successFn, errorFn) {
    $.ajax({
        url: signedOAuthRequest,
        type: "GET",
        dataType: "jsonp",
        jsonpCallback: callbackName,
        jsonp: false,
        cache: true,
        success: successFn,
        error: function (jqXHR, textStatus, errorThrown) {
            if (typeof errorFn !== 'undefined') {
                errorFn(jqXHR, textStatus, errorThrown);
            }
        }
    });
}

我做了以下更改:

添加了一个附加参数来传递成功回调。这是必需的,因为 jQuery 将为您定义回调,以便它可以检索成功的响应并对其进行解析。

删除crossdomain: true,因为它是多余的

删除了proccessData: false,因为它不影响 jsonp 请求并且您没有传递任何数据

添加了success: successFn,以便 jQuery 在成功解析 json 数据时执行successFn

将回调重命名为 callbackName 以便更清楚地了解它包含的内容。

如果您仍然坚持自己定义回调,另一种解决方案是使用脚本 dataType(取自下面的 cmets)

$.ajax({
    url: signedOAuthRequest,
    dataType: "script",
    cache: true
});

【讨论】:

  • 不幸的是,添加成功处理程序并没有改变行为。和以前一样,回调运行并传递一个格式良好的 json 对象;紧随其后的是错误处理程序运行。在错误处理程序中,jqXHR.status 是 200,jqXHR.statusText 是“成功”,textStatus 是“parsererror”,errorThrown.message 是“未调用 fn.home.jsonp.getRecentlyConnectedEoatCallback”。但是那个函数正在被调用。据我所知,这里唯一的错误是 jQuery 抛出错误。
  • 停止自己定义函数! jQuery 将为您定义它。传递匿名函数,或对与您传递的回调名称不同名称的函数的引用。
  • signedOAuthRequest 是一个签名的 OAuth 请求。如果您允许 jQuery 使用其他查询参数来处理它,您将破坏 OAuth。这就是设置cache: true 的原因;它阻止 jQuery 将_ 参数添加到signedOAuthRequest。这也是设置jsonp: false 的原因;它可以防止 jQuery 使用 callback 参数修改 signedOAuthRequest。此外,因为它最终在请求 URL 中是必需的,所以在签名之前,callback 参数必须包含在 URL 中
  • 如果我对您实际执行此请求的方式的假设是正确的,您应该可以这样做:pastebin.com/ZAWZ5FSH 如果可行,那么绝对没有理由按照我的方式去做如果调用得当,也可以工作。
  • @KevinB 根据文档:api.jquery.com/jQuery.ajax 弃用通知:jqXHR.success()、jqXHR.error() 和 jqXHR.complete() 回调自 jQuery 1.8 起已弃用。要为最终删除准备代码,请改用 jqXHR.done()、jqXHR.fail() 和 jqXHR.always()。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-11-15
  • 2011-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-15
相关资源
最近更新 更多