Это довольно просто при выводе текста или HTML . Ниже приведен пример.
(Однако при попытке вывести JSON вы столкнетесь с проблемами, о которых я расскажу далее.)
PHP FILE
header('Content-type: text/html; charset=utf-8');
function output($val)
{
echo $val;
flush();
ob_flush();
usleep(500000);
}
output('Begin... (counting to 10)');
for( $i = 0 ; $i < 10 ; $i++ )
{
output($i+1);
}
output('End...');
ФАЙЛ HTML
<!DOCTYPE>
<html>
<head>
<title>Flushed ajax test</title>
<meta charset="UTF-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
</head>
<body>
<script type="text/javascript">
var last_response_len = false;
$.ajax('./flushed-ajax.php', {
xhrFields: {
onprogress: function(e)
{
var this_response, response = e.currentTarget.response;
if(last_response_len === false)
{
this_response = response;
last_response_len = response.length;
}
else
{
this_response = response.substring(last_response_len);
last_response_len = response.length;
}
console.log(this_response);
}
}
})
.done(function(data)
{
console.log('Complete response = ' + data);
})
.fail(function(data)
{
console.log('Error: ', data);
});
console.log('Request Sent');
</script>
</body>
</html>
Что если мне нужно сделать это с JSON?
На самом деле невозможно загрузить один объект JSON постепенно (до его полной загрузки), потому что до тех пор, пока у вас не будет завершенного объекта, синтаксис всегда будет недействительным.
Но если в вашем ответе несколько объектов JSON, один за другим, то можно загружать по одному за раз, когда они приходят по конвейеру.
Так что я подправил свой код выше ...
Изменение строки 4 ФАЙЛА PHP с echo $val;
на echo '{"name":"'.$val.'"};'
. Это выводит серию объектов JSON.
Изменение строки 24 ФАЙЛА HTML с console.log(this_response);
на
this_response = JSON.parse(this_response);
console.log(this_response.name);
Обратите внимание, что этот элементарный код предполагает, что каждый «кусок», поступающий в браузер, является допустимым объектом JSON. Это не всегда так, потому что вы не можете предсказать, как будут поступать пакеты - вам может потребоваться разбить строку на точки с запятой (или придумать другой символ-разделитель).
Не использовать application/json
Do NOT Для изменения заголовков на application/json
- я сделал это, и я получил Google в течение 3 дней. Когда тип ответа application/json
, браузер ожидает, пока ответ не будет завершен, как в случае полного завершения. Полный ответ затем анализируется, чтобы проверить, является ли он действительным JSON. Однако наш полный ответ {...};{...};{...};
, который НЕ является действительным JSON. В методе jqXHR.done
предполагается, что произошла ошибка, поскольку полный ответ не может быть проанализирован как JSON.
Как уже упоминалось в комментариях, вы можете отключить эту проверку на стороне клиента с помощью:
$.ajax(..., {dataType: "text"})
Надеюсь, что некоторые люди находят это полезным.