Javascript.RU

Multipart XMLHTTPRequest

Update: Более новый материал по этой теме находится по адресу https://learn.javascript.ru/xhr-onprogress.

Этот способ, как ни странно, поддерживается только Firefox. На момент написания Opera и Safari под Windows не поддерживали его. Он представляет собой XHR-запрос, ответ на который может быть разделен на части. При получении новой части вызывается onload().

Вот - пример, можете попробовать его в любом браузере, и увидите, изменилось ли что-то в поддержке. Эталонное поведение: Firefox.

Тут будут сообщения

Вот - клиентский код

function runMultipart() {
	// не кросс-браузерно, все равно способ Firefox only
	var req = new XMLHttpRequest(); 
	
	req.multipart = true;
	// асинхронный запрос
	req.open("GET","/server_push/multipart.php?r="+Math.random(), true);
	req.onload = function(event) {
		var result = event.target.responseText
		
		var d = document.createElement("div")
		d.innerHTML = "onload:"+result;

		document.getElementById('xhr_multipart_dump1').appendChild(d)
	}
	req.onreadystatechange = function() {
		if (req.readyState!=4) return
		var d = document.createElement("div")
		d.innerHTML = "State:"+req.readyState+' Status:'+req.status
		document.getElementById('xhr_multipart_dump1').appendChild(d)
	}
	
	req.send(null);
}

Асинхронность запроса в случае с Multipart XMLHTTPRequest - вещь довольно условная, при установке синхронности - реально браузер подвиснет только до
первой части multipart-сообщения. Думается, это самое правильное, что можно было сделать, т.к получать весь multipart-запрос синхронно никому не нужно, для этого
есть обычные запросы.

Для обработки данных, как видно из примера, в Multipart XMLHTTPRequest используется функция onload, которая получает последний кусок из event.

Есть аналогичная функция onerror, но при вызове из javascript она не работает. Поэтому для обработки ошибок используем старый добрый onreadystatechange, который
вызывается при каждом куске данных или при ошибке.

Чтобы ответить на Multipart XMLHTTPRequest, сервер должен выбрать уникальный разделитель, и первым делом - сообщить его браузеру вместе со спец. заголовком:

header('Content-type: multipart/x-mixed-replace;boundary="УнИкАлЬНЫЙРАздеЛитЕЛЬ"');

Далее сервер может слать данные, и информировать браузер о конце каждой части ответа посылкой разделителя. Перед каждой частью ответа должен быть заголовок Content-Type.
Более подробно - вот, например, серверный код из примера выше.

// уникальный разделитель, можете использовать конкат нескльких uniqid() и т.п.
$delimiter = "boundary";

header('Content-type: multipart/x-mixed-replace;boundary="'.$delimiter.'"');

// полностью отрубаем буферизацию
while (@ob_end_flush()) {}

$header = "Content-type: text/html\r\n\r\n"; // перед каждой частью

$boundary = "--{$delimiter}\n"; // между частями

$footer = "--{$delimiter}--\n"; // в конце

$max = 10;
 
for ($i = 1; $i <= $max; $i++){	
	echo $header; # Заголовок перед каждой частью ответа	
	echo "$i\n"; # пишем сообщение	
	echo $boundary; # и выводим границу между сообщениями
	sleep(1);    
}

// завершающее сообщение
echo $header;
echo "-1";
echo $footer;
  • минимальная задержка и трафик
  • нет индикации загрузки
  • данные нельзя сжимать
  • Firefox(Gecko) only (?)

Замечательный способ, но работает только в движке Gecko, т.е Firefox и родственные браузеры.


Автор: Вадим (не зарегистрирован), дата: 28 ноября, 2008 - 22:36
#permalink

да уж, и зачем тогда это нужно если только Лиса поддерживает?


Автор: Илья Кантор, дата: 30 ноября, 2008 - 13:35
#permalink

Ну варианта 2

1) пишется приложение только под "Лису"
2) этот способ используется для лисы а для других браузеров - другой


Автор: Гость (не зарегистрирован), дата: 2 октября, 2009 - 02:08
#permalink

Chrome работает с ним


Автор: Илья Кантор, дата: 2 октября, 2009 - 21:50
#permalink

Мой тест работает только в Firefox... Может быть, у Chrome свое API ?


Автор: Гость (не зарегистрирован), дата: 24 декабря, 2009 - 18:52
#permalink

чел наверно не понял какой должен быть результат, результат то конечно есть, но не тот, что ожидается


Автор: Axdr, дата: 19 января, 2010 - 12:34
#permalink

Chrome поддерживает.
Только немного по-другому. Нужен еще один обработчик:

req.onprogress = function () {...}

Чтобы что-то увидеть в event.target.responseText, приходится послать клиенту не меньше килобайта с 4мя переводами строки.

echo str_repeat(str_repeat(' ', 256)."<br>", 4);

и еще надо добавить flush(); после каждой посылки.


Автор: AVReg (не зарегистрирован), дата: 1 апреля, 2010 - 22:43
#permalink

multipart/x-mixed-replace, на мой взгляд, единственно правильная comet-технология.
Приведу 3 аргумента:

1) всё давным давно описано в RFC.
2) куски можно передавать любого тип, размера и кодирования и, причём, вперемешку.
3) Content-Length избавляет от тупого ресурсоёмкого постоянного grep-а.

По моим наблюдениями, Опера и Хром начинают поддерживать multipart/x-mixed-replace, однако пока через пень-колоду.
Например, Опере пофиг Content-Length очередного куска,
она будет ждать boundary след. блока прежде чем начать обработку.

Всё было бы хорошо, но "браузер для овощей" упорно не хочет поддерживать x-mixed-replace.


Автор: Arech (не зарегистрирован), дата: 2 июля, 2011 - 11:16
#permalink

Всё бы хорошо с этим методом, но есть одна проблема, которую мне не удалось решить (по видимому это баг в фаерфоксе), которая снижает до нуля всю ценность метода. Суть в том, что после прихода первого пакета с данными, перестают работать обработчики ошибок соединения; они просто ни на что не реагируют, ни error, ни abort, ни onreadystatechange. Можно соединение порвать любым способом, но никаких событий в JS это не сгенерирует и таким образом реализовать логику обработки ошибок невозможно. А без обработки ошибок, возможности вовремя и быстро перепослать запрос, ценности в методе нет никакой...

Альтернативой является эмуляция EventSource, причём не абы какая (тыщи их), а построенная на POST / readyState==3, как https://github.com/Yaffle/polyfills/blob/master/eventsource.js. Там по ловятся те ошибки, которые проскакивают в этом методе.


Автор: daisykale (не зарегистрирован), дата: 17 мая, 2021 - 09:56
#permalink

It's a great piece of information, when I search for it, I don't know how to use it scribble io


Автор: yangyeo339 (не зарегистрирован), дата: 30 декабря, 2022 - 10:09
#permalink

Tool to help sort messy letters into words quickly


Автор: yangyeo339 (не зарегистрирован), дата: 30 декабря, 2022 - 10:10
#permalink

word unscrambler Tool to help sort messy letters into words quickly


Автор: Nanisa1 (не зарегистрирован), дата: 28 февраля, 2023 - 06:48
#permalink

Making the best decisions for your life is a challenge in the interesting life simulator BitLife. Are you prepared to face all the obstacles the world has to offer, including a complicated life filled with difficult choices, and many ups, and downs? Then try to lead your character on a lovely journey in this fantastic free online game. Relationships and a variety of activities based on your age, wealth, and employment can either make for a lovely life or a terrible hell on Earth.


Автор: 온라인카지노사이트 (не зарегистрирован), дата: 9 марта, 2023 - 07:47
#permalink

I accidentally searched and visited your site. I still saw several posts during my visit, but the text was neat and readable. I will quote this post and post it on my blog. Would you like to visit my blog later? 온라인카지노사이트


Автор: 토토사이트 (не зарегистрирован), дата: 27 марта, 2023 - 12:25
#permalink

What a post I've been looking for! I'm very happy to finally read this post. 토토사이트 Thank you very much. Can I refer to your post on my website? Your post touched me a lot and helped me a lot. If you have any questions, please visit my site and read what kind of posts I am posting. I am sure it will be interesting.


Автор: betterwound (не зарегистрирован), дата: 15 декабря, 2023 - 10:37
#permalink

I still saw several posts during my visit, but the text was neat and readable. I will quote this post and post it on my blog. geometry dash


Отправить комментарий

Приветствуются комментарии:
  • Полезные.
  • Дополняющие прочитанное.
  • Вопросы по прочитанному. Именно по прочитанному, чтобы ответ на него помог другим разобраться в предмете статьи. Другие вопросы могут быть удалены.
    Для остальных вопросов и обсуждений есть форум.
P.S. Лучшее "спасибо" - не комментарий, как все здорово, а рекомендация или ссылка на статью.
Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Разрешены HTML-таги: <strike> <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <u> <i> <b> <pre> <img> <abbr> <blockquote> <h1> <h2> <h3> <h4> <h5> <p> <div> <span> <sub> <sup>
  • Строки и параграфы переносятся автоматически.
  • Текстовые смайлы будут заменены на графические.

Подробнее о форматировании

CAPTCHA
Антиспам
6 + 14 =
Введите результат. Например, для 1+3, введите 4.
 
Текущий раздел
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Дерево всех статей

Последние комментарии
Последние темы на форуме
Forum