【问题标题】:json_encode and jQuery .ajax() not playing nicely ** output_buffering **json_encode 和 jQuery .ajax() 不能很好地发挥 ** output_buffering **
【发布时间】:2014-05-15 05:16:21
【问题描述】:

我设置了一个表单,它将接受用户的一些输入并通过 jQuery 的 .ajax() 函数将其发布到 URL。该 URL 位于一个单独的子域上,但我已经设置了 CORS,并且这方面的一切工作正常。

服务器端发生的情况是表单被验证,如果检测到错误(表单中的错误完成不正确),我将返回以下 JSON:

{"success": "false", "error": "Whatever the error is"}

这对我有用,所以我知道一般设置是正确的。

当表单有效时,我执行数据库查询以检索一堆文件的详细信息,将其作为数组接收,并将所有这些作为 JSON 连同成功消息一起传回。此场景的 JSON 大致如下:

{"success": "true", "files": [{"id":"4","file_name":"data_zones_scotland_2001.csv","nice_name":"Data Zone - Scotland","description":"","type":"1","coverage":"Scotland","distribution":"public","pack_type":"LSOAs, MSOAs, Data Zones, Intermediate Zones","link":"https:\/\/s3-eu-west-1.amazonaws.com\/data_zones_scotland_2001.csv?Expires=1396528176&Signature=V8ojfXhoH5eggIjwix265KGbr0M%3D"},{"id":"8","file_name":"intermediate_zones_scotland_2001.csv","nice_name":"Intermediate Zone - Scotland","description":"","type":"1","coverage":"Scotland","distribution":"public","pack_type":"LSOAs, MSOAs, Data Zones, Intermediate Zones","link":"https:\/\/s3-eu-west-1.amazonaws.com\/intermediate_zones_scotland_2001.csv?Expires=1396528176&Signature=ieaZYnZCz%2BpnJmWLeq5ygpJ9zNM%3D"}]}

为长字符串道歉,但我想把它全部放在那里以防我错过了什么。

我遇到的问题是,当我把它传回去时,我得到一个No 'Access-Control-Allow-Origin' header is present on the requested resource 错误。我知道情况并非如此,并且我已经测试了使用curl -i http://url... 设置的标题。取出 files 数组并仅返回 {"success": "true"} 工作正常,这向我表明 files 数组中的 JSON 格式错误,但是通过 JSONLint 传递该字符串告诉我 JSON 是有效的。

由于我所做的一切似乎都是正确的,因此对于下一步该去哪里我已经没有想法了。处理 POST 的 jQuery 代码如下:

$.ajax({
    url: "http://domain.com/api/download-request",
    type: "POST",
    data: postData,
    dataType: 'json'
})
.done( function(data){
    console.log(data);
}); 

如果能提供任何关于下一步该去哪里的线索,我将不胜感激。

* 更新 * 为了解决这个问题,我首先过滤从数据库接收到的数据,认为字符串中有东西破坏了输出。我已经到了这样一个地步,我似乎通过限制返回的记录数量来将其缩小到一个特定的记录,直到它被打破。在检索 just 这条记录后,虽然它再次起作用。我坚持了下来,然后注意到当 JSON 字符串达到一定长度(大约 600 个字符)时会产生错误。

我已经进入 php.ini 试图在其中找到一个限制,一旦我将 output_buffering 的大小从 4096 增加到 8192(加倍),整个事情就开始工作了。我应该提一下,DB 的输出没有 URL,大大缩短了字符串长度,所以一旦我将它们添加回应用程序中,就会再次中断,直到我将缓冲区增加到 16384(再次加倍)。

现在应用程序可以运行,但这显然不是最好的处理方式。有没有一种方法可以让我动态地进行 output_buffering 或更改 echo 的工作方式,以便 PHP 不会用完缓冲区?

【问题讨论】:

  • 听起来像是跨域 ajax 调用问题。尝试在写入 JSON 的 php 文件中设置 Access-Control-Allow-Origin 标头。就个人而言,为了确定 ajax 调用是否出现问题,我设置了不同的状态码。 4XX 和 5XX 代码使您在您的 $.ajax 调用中最终进入 error/fail 回调。
  • 如果成功,您将返回一段 Json,其中包含完整的 url。我怀疑问题不在于接收和解析此 Json,而在于获取实际文件,因为它位于不同的域中。
  • 谢谢@Johan,但Access-Control-Allow-Origin 标头已经设置在那里,只要我不返回 JSON 中的文件数组,一切都会正常进行。
  • @MattAsbury 你试过crossDomain: true 作为ajax 选项吗?
  • @Johan 我刚刚尝试过,它返回了同样的错误。

标签: php jquery ajax json output-buffering


【解决方案1】:

问题是输出缓冲区已满。增加缓冲区大小或关闭缓冲区可解决此问题。

【讨论】:

    【解决方案2】:

    使用 JsonP 代替 json。

    $.ajax({
     url:"testserver.php",
     dataType: 'jsonp', // Notice! JSONP <-- P (lowercase)
     success:function(json){
         // do stuff with json (in this case an array)
         alert("Success");
     },
     error:function(){
         alert("Error");
     }      
    });
    

    同时你可能需要用回调函数包装数据,只是为了表示jsonp数据。 查看此链接以获取有关如何执行此操作的更多信息:allow cross domain ajax requests

    参考:

    快乐编码:)

    【讨论】:

    • 他的服务器正在返回一个 JSON 字符串,而不是包装在函数中。因此,jsonp 无济于事。另外,他和服务端的通讯也很好,不用改类型。
    • 我也觉得jsonp和POST不兼容?
    • @Johan: 跨域,你真的不能用json数据和服务器通信,你需要使用jsonp类型的数据传输。要在服务器上启用跨域访问,有几件事,比如启用像header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET, POST'); 这样的标头,并且还需要用回调包装返回数据。
    • @MattAsbury: 是的,它不一样。与普通的 json 数据相比,jsonp 实际上包含一个回调函数。
    • 好吧,OP 可以传递较小的对象就好了。因此,即使该错误听起来像是 CORS 问题,但在我看来,问题出在其他地方。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    • 1970-01-01
    • 1970-01-01
    • 2015-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多