为什么jQuery ajax jsonp请求会出错?

时间:2012-07-12 06:44:00

标签: jquery ajax django datatables

"fnServerData": function( sUrl, aoData, fnCallback, oSettings ) {
            oSettings.jqXHR = $.ajax( {
                "url": sUrl,
                "data": aoData,
                "success": fnCallback,
                "error":function(msg){
                    alert(msg);
                },
                "dataType": "jsonp",
                "cache": false
            } );
        },

当我发出请求时,服务器会给出响应。

Status Code: 200 OK
Cache-Control: max-age=0
Content-Language: en
Content-Type: application/javascript
Expires: Thu, 12 Jul 2012 06:23:18 GMT
Last-Modified: Thu, 12 Jul 2012 06:23:18 GMT
Vary: Accept-Language, Cookie

响应体中的json数据。

但是ajax代码说它有错误,并进入“错误”代码块。

为什么它的状态为200时会出错?

更新:

在Django服务器代码中:

            response_dict = {}                
            response_dict.update({'aaData': aaData})
            response_dict.update({'sEcho': sEcho, 'iTotalRecords': iTotalRecords, 'iTotalDisplayRecords':iTotalDisplayRecords, 'sColumns':sColumns})
            response = HttpResponse(simplejson.dumps(response_dict), mimetype='application/javascript')

1 个答案:

答案 0 :(得分:3)

服务器响应是否包含带填充的JSON?

您看,有两种方法可以从不同的域接收数据:

  1. CORS是新的,但需要从服务器发送单独的Access-Control-Allow-Origin标头。浏览器支持在某种程度上也受到限制。

  2. JSONP不依赖于服务器标头,而是要求它使用所谓的'padding'发送回JSON数据

    callback('{"your": ["json", "data"}')
    

    然后,您的JavaScript库(在本例中为jQuery)将其包装到一个新的script标记中,诱使您的浏览器对其进行评估。在这个callback函数中,jQuery解析JSON数据并将其发送到fnCallback。之后,它会从页面中删除不必要的script标记。一般来说,这是一个非常脆弱的解决方案,但它在实践中有效。例如,如果服务器没有填充JSON数据,您最终会在script标记内包含以下代码:

    '{"your": ["json", "data"}'
    

    请注意,它只是一个字符串而不执行任何操作。因此,检查服务器是否发送包装的JSON而不是原始JSON。我之前遇到过相同的问题很多次,这帮助了我。


  3. 编辑:由于您发布了服务器端代码,我假设您可以修改它。我从未玩过Django,但我会尝试给你提示:

    1. 在您收到的request内,应该有一个名为callback的参数 - 这就是jQuery发送给您的内容以及您应该用于填充的内容。把它放在某处:

      # Like I said I don't know the exact API but you get the idea
      callback = request.GET["callback"]
      
    2. 之后 pad 您的回复,然后再将其发送给客户:

      response = HttpResponse( # Put callback name before the actual JSON
                     callback + "(" + simplejson.dumps(response_dict) + ");", 
                     mimetype='application/javascript')
      
    3. 这应该有用。