带有 jsonp 内容类型的 jQuery.ajax 请求后的解析器错误

Posted

技术标签:

【中文标题】带有 jsonp 内容类型的 jQuery.ajax 请求后的解析器错误【英文标题】:parsererror after jQuery.ajax request with jsonp content type 【发布时间】:2011-07-18 13:40:50 【问题描述】:

我正在使用 jQuery 版本 1.5.1 执行以下 ajax 调用:

$.ajax(
    dataType: 'jsonp',
    data:  api_key : apiKey ,
    url: "http://de.dawanda.com/api/v1/" + resource + ".json",
    success: function(data)  console.log(data); ,
    error: function(jqXHR, textStatus, errorThrown)  console.log(errorThrown); console.log(textStatus); 
);

服务器响应一个有效的 json 对象:


  "response": 
    "type":"category",
    "entries":1,
    "params":
      "format":"json",
      "api_key":"c9f11509529b219766a3d301d9c988ae9f6f67fb",
      "id":"406",
      "callback":"jQuery15109935275333671539_1300495251986",
      "_":"1300495252693"
    ,
    "pages":1,
    "result":
      "category":
        "product_count":0,
        "id":406,
        "restful_path":"/categories/406",
        "parent_id":null,
        "name":"Oberteile"
       
     
   
 

但从不调用成功回调,而是错误回调产生以下输出:

jQuery15109935275333671539_1300495251986 was not called
parsererror

为什么会这样?

我没有为 jQuery 使用额外的库。

编辑:

如果我尝试使用“json”作为数据类型而不是“jsonp”进行 ajax 调用,服务器会以空字符串响应。

【问题讨论】:

【参考方案1】:

JSONP 要求将响应包装在某种回调函数中,因为它通过将脚本标记注入文档作为从另一个域加载数据的机制来工作。

基本上,脚本标签会像这样动态插入到文档中:

<script src="http://the.other.server.com/foo?callback=someFn"></script>

callback 取决于您调用的资源,但参数通常为 callback

someFn 然后用于处理从服务器返回的数据,因此服务器应该响应:

someFn(theData: 'here');

someFn 作为请求的一部分传递,因此服务器需要读取它并适当地包装数据。

这一切都假设您从另一个域获取内容。如果是这样,您将受到同源策略的限制:http://en.wikipedia.org/wiki/Same_origin_policy

【讨论】:

问题中的 API 是供应商的公共 API。它只是将调用限制为仅 jsonp。 Jsonp 调用得到应答,但作为普通 Json 对象。 在这个例子中,someFn 是回调,服务器应该响应:jQuery15109935275333671539_1300495251986(...); 感谢上帝,希望他们能添加一些文件 这个我看不懂。你的意思是我需要将来自服务器的响应包装起来,例如: $callBack($myJsonResult);我会在服务器端做那个? @AdamMorris 服务器如何知道该功能?我的意思是 jQuery15109935275333671539_1300495251986 中的那个长数字?你如何将这些信息传递给服务器?【参考方案2】:

你真的不应该在这里指定 jsonp。只需使用 json 因为您只是收到一个 JSON 字符串。 json(带填充的json)需要一个javascript函数执行。在这种情况下,您需要在查询字符串中指定“回调 =”。我想这就是。jQuery 也无法处理这个问题的原因,是有一个名为 callback 的属性。

【讨论】:

如果我只对请求使用 json,我会得到一个空字符串作为答案。会不会是api坏了?如果是这样,有没有办法在 js 中破解它? 你的意思是“jsonp(带填充的json)”,而不是“json(带填充的json)”【参考方案3】:

尝试使用 $.parseJSON 将响应读入对象:

success: function(data) 
    var json = $.parseJSON(data);

【讨论】:

不,在使用 jsonp 内容类型的 jQuery.ajax 请求后不会修复解析器错误【参考方案4】:

有一个小错误 :) 你必须请求 .js 而不是 .json。

$.ajax(
    dataType: 'jsonp',
    data:  api_key : apiKey ,
    url: "http://de.dawanda.com/api/v1/" + resource + ".js",
    success: function(data)  console.log(data); ,
    error: function(jqXHR, textStatus, errorThrown)  console.log(errorThrown); console.log(textStatus); 
);

啊,您是否注意到,有一个 api 客户端? https://github.com/dawanda/dawanda-api-client-js

【讨论】:

非常感谢您的回答! API 现在就像一个魅力 :) 我一开始使用的是 api 客户端,但我想坚持只使用 jquery 的方法。 您也可以将客户端与 jQuery 一起使用。它将自动检测 Prototype 或 jQuery 并使用给定的方法。 (Y)【参考方案5】:

升级到 Jquery 1.5 并尝试跨域调用后,我遇到了同样的问题。最终我发现 $.getJSON 有效。具体来说,

$.getJSON(url,
    function(data)
        yourFunction(data);
       return false;
    );

我使用的网址是这样的:

var url = WEB_SERVER_URL;
url = url + "&a=" + lat;
url = url + "&b=" + lng; ....
url = url + "&jsoncallback=?";

在另一台服务器上运行的服务器中,我可以控制此代码:

PrintWriter writer = response.getWriter();
String jsonString = json.toString(JSON_SPACING);
String callback = request.getParameter("jsoncallback");
// if callback in URL and is not just the "?" (e.g. from localhost)
if (callback != null && callback.length() > 1)

    writer.write(callback + "(" + jsonString + ");");

else

    writer.write(jsonString);

(json对象是JSONObject的一个实例,代码可以看这里http://www.json.org/java/)

【讨论】:

【参考方案6】:

当您使用 jsonp 作为数据类型(进行跨域请求)时,Jquery 生成随机函数并将请求的 url 作为名为回调(callback=?)的查询字符串附加到请求的 url,您需要附加响应 json 数据作为该函数的参数如下所示 -

url : http://www.dotnetbull.com/cross-domain-call.ashx?ref=jquery-jsonp-request
url call by ajax :
http://www.dotnetbull.com/cross-domain-call.ashx?ref=jquery-jsonp-request&callback=jQuery1510993527567155793_137593181353

响应数据应如下所示:

 string callback = context.Request.QueryString["callback"];

 if (!string.IsNullOrEmpty(callback))
   context.Response.Write(string.Format("0(1);", callback, jc.Serialize(outputData)));
else
   context.Response.Write(jc.Serialize(outputData));

了解更多信息: parsererror after jquery.ajax request with jsonp content type

【讨论】:

【参考方案7】:

并非所有服务器都支持 jsonp。它要求服务器在其结果中设置回调函数。我使用它从返回纯 json 但不支持 jsonp(但将来可能)的站点获取 json 响应:

function AjaxFeed()

    return $.ajax(
        url:            'http://somesite.com/somejsonfile.php',
        data:           something: true,
        dataType:       'jsonp',

        /* Very important */
        contentType:    'application/json',
    );


function GetData()
    AjaxFeed()

    /* Everything worked okay. Hooray */
    .done(function(data)
        return data;
    )

    /* Okay jQuery is stupid manually fix things */
    .fail(function(jqXHR) 

        /* Build html and update */
        var data = jQuery.parseJSON(jqXHR.responseText);

        return data;
    );

【讨论】:

我真的希望这能奏效,因为它看起来很聪明,但 jqXHR.responseText 总是未定义...【参考方案8】:

确保您调用的服务能够以 JsonP 格式返回数据。

如果你使用asp.net webapi,你可以使用WebApiContrib.Formatting.Jsonp,它是开源的。

确保您在 WebApiConfig.Register 中有如下一行。

config.Formatters.Insert(0, new JsonpMediaTypeFormatter(new JsonMediaTypeFormatter(), "callback"));

我在这上面拉头发。希望这对某人有所帮助。

【讨论】:

【参考方案9】:

在我没有附加参数“callback=?”之前,我遇到了同样的问题或“c=?”在网址中。

喜欢:“http://de.dawanda.com/api/v1/”+资源+“.json&c=?” 可以解决你的问题。它对我有用。

【讨论】:

以上是关于带有 jsonp 内容类型的 jQuery.ajax 请求后的解析器错误的主要内容,如果未能解决你的问题,请参考以下文章

JSONP 响应 http 内容类型标头

带有jquery的jsonp [关闭]

带有 jsonp 的 AngularJS 资源服务失败

带有 HttpHeaders 的 Angular 5 JSONP 请求

为啥跨域 JSONP 安全,但跨域 JSON 不安全?

带有 wordpress json 插件的 Kendo UI Jsonp 示例