【问题标题】:jQuery.ajax() for JSONP returns 200, but a parse error runs the error callback instead of the success callbackJSONP 的 jQuery.ajax() 返回 200,但解析错误运行错误回调而不是成功回调
【发布时间】:2016-06-04 08:17:43
【问题描述】:

首先,我知道网站上有类似的帖子,但都没有解决我的问题。

我想从网络服务器获取 JSON 文件。 JSON 文件由 JSONLint 检查,因此语法被验证为 OK。 JSON 数据从类似于以下的 URL 检索:www.examplewebsite.com/data.json

我的 jQuery Ajax 代码:

$.ajax({

    url:url",
    dataType:"jsonp",
    contentType: "application/json",
    type:"get",
    success:function(){
        console.log("OK");
    },
    error:function(data,status,error){
        console.log(data " "status+" "+error);
    }
});

这是错误:

:parsererror 错误:没有调用 jQuery222030055767520832166_1465026956736

到目前为止我做了什么:

  • 添加了回调函数 (jsonpCallback: fname) (我真的很想知道,如果我们必须添加回调函数才能到达服务器端 JSON?)函数 fname 有效(alert("OK");),但我仍然得到错误。其中一条错误消息是“未调用未定义”
  • 添加了 jsonp:false 选项
  • 将 dataType:jsonp 更改为 json 但得到 Access-Control-Allow-Origin 错误
  • 仔细检查生成的 JSON 是否有效

更新1

我的json内容(用于测试):

[{
  "id": 1,
  "first_name": "Sara"
}, {
  "id": 2,
  "first_name": "Lois"
}, {
  "id": 3,
  "first_name": "Annie"
}, {
  "id": 4,
  "first_name": "Gregory"
}, {
  "id": 5,
  "first_name": "Fred"
}, {
  "id": 6,
  "first_name": "Antonio"
}, {
  "id": 7,
  "first_name": "Denise"
}, {
  "id": 8,
  "first_name": "Susan"
}, {
  "id": 9,
  "first_name": "Jeffrey"
}, {
  "id": 10,
  "first_name": "Jean"
}]

更新2 根据@Michael 的解释,我更新了标头和 ajax 代码 dataType:"json" 但我得到了 Access-Control-Allow-Origin 错误。我对 json 文件的标头检查结果:

HTTP/1.1 200 OK => 
Date => Sun, 05 Jun 2016 00:21:59 GMT
Server => Apache
Last-Modified => Sat, 04 Jun 2016 22:27:58 GMT
Accept-Ranges => bytes
Content-Length => 440
Access-Control-Allow-Origin => *
Access-Control-Allow-Headers => origin, x-requested-with, content-type
Access-Control-Allow-Methods => PUT, GET, POST, DELETE, OPTIONS
Keep-Alive => timeout=10, max=200
Content-Type => application/json
Connection => close

有什么想法吗? PS:另外,我尝试写另一个方法(IfModule)仍然有问题。

【问题讨论】:

  • 您是否尝试过将数据类型全部删除?
  • 你能显示从服务器返回的实际 JSONP 数据吗? JSON 和 JSONP 之间存在语法差异,因此查看生成解析错误的实际数据非常重要。
  • 是的,JSON 不是 JSONp
  • @Julian 我已经试过了,我得到了 Access-Control-Allow-Origin 错误,我也添加了我的 json 文件。
  • “值得注意的是,空响应也被认为是无效的 JSON;您可以返回 {} 或 null 例如验证为 JSON。”我在这个答案stackoverflow.com/questions/6186770/… 上找到了这句话。服务器是否有可能提供一个空响应,即使它导致 200?

标签: jquery json ajax jsonp


【解决方案1】:

您尝试检索的数据是 JSON,而不是 JSONP。如您所见,通过 Ajax 从另一个域请求 JSON 将导致 Access Control Allow Origin 错误。 Ajax 将允许从不同域检索 JSONP,但内容必须实际上是 JSONP,否则您会收到解析错误,如您所见。

那么,你能做什么?如果您控制请求 JSON 数据的服务器,则可以通过响应标头处理来自您的域的请求。您只需要设置这些标题:

  • Access-Control-Allow-Origin:你的服务器
  • 访问控制允许方法:GET、PUT、POST、DELETE、OPTIONS
  • 访问控制最大年龄:3600
  • 访问控制允许标头

一旦你有了它,你可以简单地做一个 JSON(不是 JSONP)Ajax 调用,然后你就可以设置好了。

如果您出于某种原因不能依赖 CORS,并且您确实控制了远程服务器,只需将数据返回为 JSONP 而不是 JSON。

但是,如果您不控制远程服务器或由于某种原因无法使用 CORS,事情很快就会变得很奇怪。 How do I send a cross-domain POST request via JavaScript? 的答案很好地解释了如何使用 iframe 和 window.postMessage 进行这项工作。当然,该示例是针对 POST 的,但如果您只是尝试从远程服务器获取信息,则所有信息都有效。

在这种情况下非常很难给出准确的答案,因为根本没有关于您是否控制远程服务器的信息,也没有关于您自己的服务器使用什么语言/技术堆栈的信息。 4 jQuery Cross-Domain AJAX Request methods 文章中对各种解决方案进行了很好的介绍,其中一种可能会解决您的问题(在决定选择一种之前,请务必注意每种解决方案的缺点)。

如果此时你还处于僵局,你应该考虑使用自己的服务器作为代理,这样Ajax调用就可以对你的服务器进行,​​然后你的服务器就可以进行跨域调用了远程服务器检索数据。这将导致更长的响应时间,但会准确为您提供所需的内容,并完全控制流程的各个方面。通常只需几行代码即可完成此操作,但确实需要在服务器上完成。

考虑这个 Ruby on Rails 代理示例:

def json_proxy
  Net::HTTP.start("www.examplewebsite.com") do |http|
    render json: http.get("/data.json")
  end
end

您的服务器语言和/或技术堆栈可能不同,但这就是要点。如果您愿意,您可以修饰和添加新功能,包括能够通过将请求详细信息传递给代理来对所有请求使用单个代理。您可以使用这样的代理执行验证、替换,甚至将多个响应合并在一起。它可以成为您工具带中的强大工具。

有关 CORS 的更多信息,请参阅W3C Cross-Origin Resource Sharing 规范以了解有关 CORS 工作原理的详细信息。您还应该查看 html5rocks.com Using CORS 中的详细报道,因为这涵盖了 CORS 工作原理以及您在 CORS 环境中可以做什么的很多基础知识。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-31
    • 2012-02-16
    • 2012-02-15
    • 2012-06-30
    • 2012-07-31
    • 2019-04-01
    • 1970-01-01
    • 2012-05-30
    相关资源
    最近更新 更多