Очень длинный ответ json останавливается и отправляет заголовки HTTP как текст, затем продолжается - PullRequest
6 голосов
/ 21 сентября 2011

Я полностью потерян с этой проблемой.

У меня есть запрос 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

Символы ... представляют собой одно и то же "{" test ":" длина теста "}," строка

Таким образом, ответ, по-видимому, имеет вид:

  • Последняя часть данных
  • http заголовок ответа распечатывается в теле
  • Символы '5b03d'
  • Первая часть данных
  • Символ '0'

НЕТ ТОЧНОЙ длины отклика, при которой это происходит, однако она вполне подходит для 360791 символа, но не для 372797 символов.

Я использую фреймворк Yii PHP , но искал повсюду и ничего не видел на форумах.

Мне кажется, что веб-сервер разделяет ответ на несколько частей или делает тайм-аут и начинает снова.

Или возможно максимальный размер возврата?

EDIT _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ ___

Я попробовал тип содержимого application / json, как это было предложено, но это все еще происходит. Текстовая часть заголовка, возвращаемая в теле, выглядит следующим образом (при использовании кодирования 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_ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ __ _ _

Я добавил длину содержимого в мои заголовки, и полученный заголовок ответа все еще распечатывается в теле как:

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;

Ответы [ 4 ]

2 голосов
/ 13 ноября 2012

У меня есть сервер Java, который отвечает кодом json, давая мне повреждение, которое вы, кажется, описываете.Когда возвращаемый JSON становится большим, текст поврежден.Разные браузеры показывают разные искажения, но один и тот же браузер очень часто портит в одних и тех же местах.

В одном из моих тестов я отправил 9492 байта.Первые 1495 были в порядке, следующие 5204 отсутствовали, хотя анализ Wireshark показал байты в потоке tcp.Затем следующие 1495 байтов были благополучно доставлены, а следующие 1298 отсутствовали.

Эти числа являются примером.Другие браузеры будут отображать различные искажения для одной и той же отправки.Одни и те же браузеры могут повторять практически одинаковые номера.Например, первое повреждение почти всегда в одном и том же байте для Chrome.

Количество json, ограниченное, скажем, 4000 байтами, всегда успешно.

Я не нашел способа остановить chunkin, задав в этом контексте длину содержимого.Просто чтобы дать вам представление о достоверности кодов: один и тот же Javaserver более 12 лет обслуживает браузеры с html без порчи.Но ответ Json отправляется выходным потоком, а я не устанавливаю заголовки.

Я думаю, что заголовки составляются сервером apache, когда я отправляю из своей собственной java-программы.

2 голосов
/ 21 сентября 2011

то, что вы видите здесь, - это кодированная передача по частям - http://en.wikipedia.org/wiki/Chunked_transfer_encoding

это вызывает проблемы в сочетании с типом содержимого text / html.установка типа контента на application / json должна решить проблему.

1 голос
/ 22 сентября 2011

Я не нашел ответа на этот вопрос, однако выделил проблему.

В стандартном 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;

?>

и пошел к нему в браузере и получил ту же проблему.

Может ли кто-нибудь еще попробовать это для меня? (я пробовал на двух компьютерах сейчас с одинаковым результатом)

0 голосов
/ 23 октября 2013

У меня никогда не было проблем с отправкой кускованного Джсона.Но ..

Правильный контент будет разбит на части, потому что длина контента неизвестна, в то время как PHP передает то и это клиенту.

  1. ob_start () ... ob_end_flush () гарантирует, что контент будет отправлен сразу, а заголовок content-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. Я думаю, что длина содержимого 373 КБ далека от переполнения памяти?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...