2011-09-21 62 views
5

我完全失去了这个问题。非常长的json响应停止并发送HTTP头文件,然后继续

我有一个ajax查询,它得到一个JSON响应。查询在大多数情况下都能正常工作,但是当json响应非常大时似乎很失败。

问题是响应的形式结束:

...est":"test length"}]]} 
HTTP/1.1 200 OK 
Date: Wed, 21 Sep 2011 17:10:32 GMT 
Server: Apache/2.2.11 (Win32) mod_ssl/2.2.11 OpenSSL/0.9.8k PHP/5.3.0 
X-Powered-By: PHP/5.3.0 
Expires: Thu, 19 Nov 1981 08:52:00 GMT 
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 
Pragma: no-cache 
Keep-Alive: timeout=5, max=90 
Connection: Keep-Alive 
Transfer-Encoding: chunked 
Content-Type: text/html 

5b03d 
{"ResultsInfo":{"RequestID":"131661886010","FeedCompletion":{"0":"100"}},"ResultsData":[[{"test":"test length"},{"test":"test length"}, 

...0 

该...表示多个相同的“{”测试“:”测试长度“}的,”串

所以的效应初探似乎是以下形式:

  • 最后数据
  • HTTP响应报头在主体打印出的部分
  • 字符“5b03d”
  • 的数据的第一部分
  • 字符“0”

没有响应的精确长度,这发生在但它是在360791个字符,但不精在372797个字符。

我使用的Yii PHP框架,但搜索范围很广,没有看到任何有论坛的东西。

在我看来,网络服务器将响应分成几块或超时并重新开始。

或者也许有最大的回报大小?

编辑 _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ ___

我尝试过应用程序/ json内容类型的建议,但它是stil发生。即在人体中返回的标头的TES文本部分是(使用applciaiton时/ JSON编码)如下:

HTTP/1.1 200 OK 
Date: Thu, 22 Sep 2011 08:48:28 GMT 
Server: Apache/2.2.11 (Win32) mod_ssl/2.2.11 OpenSSL/0.9.8k PHP/5.3.0 
X-Powered-By: PHP/5.3.0 
Expires: Thu, 19 Nov 1981 08:52:00 GMT 
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 
Pragma: no-cache 
Keep-Alive: timeout=5, max=89 
Connection: Keep-Alive 
Transfer-Encoding: chunked 
Content-Type: application/json 

如何关闭分块编码为这个特殊的脚本?

**编辑2_8 _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ _

我现在已经增加了一个内容长度我的头和响应报头,我得到的身体还在打印出来:

HTTP/1.1 200 OK 
Date: Thu, 22 Sep 2011 11:55:39 GMT 
Server: Apache/2.2.11 (Win32) mod_ssl/2.2.11 OpenSSL/0.9.8k PHP/5.3.0 
X-Powered-By: PHP/5.3.0 
Expires: Thu, 19 Nov 1981 08:52:00 GMT 
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 
Pragma: no-cache 
Content-Length: 372797 
Keep-Alive: timeout=5, max=90 
Connection: Keep-Alive 
Content-Type: application/json 

所以看起来是分块不再被寄的。然而,同样的问题存在 - 响应有内容,然后打印出标题,然后更多的内容。

**现在唯一的区别是它没有响应中的'5b03d'或'0'字符。

EDIT_3_ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ _

至于问这里是我的php代码的摘要

$dataArray = array(
    'ResultsData'=>array(
      array('test'=>'test length'), 
      array('test'=>'test length'), 
      array('test'=>'test length'), 
      ... 
)); 

$return = json_encode($dataArray); 

header('Content-Length: '.strlen($return)); 
header('Content-type: application/json'); 

echo $return; 
+0

你的php代码是什么样的?这是非常不寻常的。 –

回答

2

你在这里看到的是什么块传输编码 - http://en.wikipedia.org/wiki/Chunked_transfer_encoding

这将导致与内容类型为文本/ HTML组合问题。将内容类型设置为application/json应该可以解决问题。

+0

嗨,我已经改变我的内容类型为应用程序/ json根据我上面的编辑,它仍然在发生(编码仍然分块) –

1

我还没有找到这个问题的答案,但有孤立的问题。

在一个标准的PHP文件,我写了这个代码:

<?php 

// Make a large array of strings 
for($i=0;$i<10000;$i++) 
{   
    $arr[] = "testing this string becuase it is must longer than all the rest to see if we can replicate the problem. testing this string becuase it is must longer than all the rest to see if we can replicate the problem. testing this string becuase it is must longer than all the rest to see if we can replicate the problem."; 
} 

// Create one large string from array 
$var = implode("-",$arr); 

// Set HTTP headers to ensure we are not 'chunking' response 
header('Content-Length: '.strlen($var)); 
header('Content-type: text/html'); 

// Print response 
echo $var; 

?> 

,前往它在浏览器中,得到了同样的问题。

其他人可以试试吗?(我已经在两台电脑上试过了,结果相同)

2

我有一个Java服务器,它使用json代码响应,给我看起来描述的损坏。当返回的json变大时,文本被破坏。不同的浏览器显示不同的损坏,但相同的浏览器经常在相同的地方损坏。

在我的一个测试中,我发送了9492个字节。虽然Wireshark分析显示了tcp流中的字节,但第一个1495没有问题,接下来的5204没有找到。然后接下来的1495字节安全到达,而下一个1298字节丢失。

这些数字就是一个例子。其他浏览器会针对相同的发送出现不同的损坏。相同的浏览器可能会重复几乎相同的数字。例如,第一次腐败几乎总是在同一个字节的铬。

json数量限制为4000字节总是成功。

我还没有找到一种方法来通过在此上下文中设置内容长度来停止chunkin。只是为了让您了解代码可信度:同样的Javaserver已经为浏览器提供了超过12年的HTML,并且没有损坏。但是Json的响应是由输出流发送的,没有我设置头文件。

我认为头文件是由我自己的java程序发送时由apache服务器组成的。

0

我从来没有问题发送chunked Json。但是..

正确的内容将被分块,因为内容长度是未知的,而PHP将这个和那个回应给客户端。

  1. ob_start()... ob_end_flush()函数确保了内容将立即被发送和该内容 - lenth标题就被自动设置。

  2. 压缩数据将永远不会分块。所以: ob_start(ob_gzhandler)... ob_end_flush()是有效的。

  3. 在客户端脚本中测试你的json。

  4. 它无用重复“测试”。嵌套有一个限制。

dataArray = array('ResultsData'=> array(length0,length1,length2,...));

echo json_encode($ dataArray,JSON_NUMERIC_CHECK);

JSON_NUMERIC_CHECK从数字中去掉引号。

  1. ?5b03d?你尝试发送二进制字符串吗?

  2. 我认为373kb的内容长度远离内存溢出?