Onload

Using the iframe’s onreadystatechange

I decided to look into Internet Explorer’s iframe implementation a little bit more. It was clear that assigning something to the property didn’t produce the desired effect, but I figured there must be something else similar. I tried to attach the event handler using , which also didn’t work. Okay, clearly there was no support for the load event on the iframe. What about something else?

That’s when I recalled IE’s bizarre event that it has on documents. This is, of course, completely different than the event fired on objects. I wondered if the iframe element might support this event as well, and as it turns out, it does. The iframe element supports the property, which is changed to “interactive” and then “complete” when the contents of the iframe have been loaded. And because this is on the iframe element and not on the iframe object, there is no concern about cross-domain restrictions (experiment). The final code I ended up with is along these lines:

The check to determine if the browser is IE or not is a bit messy. I would have preferred to check for the existence of , however, this throws an error when you try to access the property prior to adding the iframe into the document. I considered using the existence of to determine whether to use , however, most other browsers now support this property, so that’s not a good enough determinant. With YUI, I’d just use to determine this (you can use whichever method suits you best).

Example HTML code 2:

This example illustrates the use of the onload event for img elements:

<head><scripttype="text/javascript">// Internet Explorer specific
function OnAbortImage () {
            var info = document.getElementById ("info");
            info.innerHTML += "<br />The loading of the image has been aborted.";
            RemoveEsc ();
        }

        function OnLoadImage () {
            var info = document.getElementById ("info");
            info.innerHTML += "<br />The image has been loaded.";
            RemoveEsc ();
        }

            // Internet Explorer specific
function OnStateChangeImage (image) {
            var info = document.getElementById ("info");
            info.innerHTML += "<br />readyState: " + image.readyState;
        }

        function RemoveEsc () {
            var esc = document.getElementById ("esc");
            esc.parentNode.removeChild (esc);
        }
    </script></head><body><spanid="info"style="color:red">The image is loading.</span><br/><br/><spanid="esc">Press the Escape key to abort the process.</span><br/><br/><imgsrc="large.bmp"width="200px"height="150px"onabort="OnAbortImage ()"onload="OnLoadImage ()"onreadystatechange="OnStateChangeImage (this)"/></body>

Did you find this example helpful?

yes
no

IE8,9: XDomainRequest

В IE8 и IE9 поддержка ограничена:

  • Не поддерживаются события, кроме .
  • Некорректно поддерживается состояние : браузер может сгенерировать его только один раз во время запроса, а не при каждом пакете данных. Кроме того, он не даёт доступ к ответу до того, как он будет до конца получен.

Дело в том, что, когда создавались эти браузеры, спецификации были не до конца проработаны. Поэтому разработчики браузера решили добавить свой объект , который реализовывал часть возможностей современного стандарта.

А обычный решили не трогать, чтобы ненароком не сломать существующий код.

Мы подробнее поговорим про в главе XMLHttpRequest: кросс-доменные запросы. Пока лишь заметим, что для того, чтобы получить некоторые из современных возможностей в IE8,9 – вместо нужно использовать .

Кросс-браузерно:

Теперь в IE8,9 поддерживаются события , и . Это именно для IE8,9. Для IE10 обычный уже является полноценным.

Обычно ответы на запросы кешируются, как и обычные страницы.

Но IE9- по умолчанию кеширует все ответы, не снабжённые антикеш-заголовком. Другие браузеры этого не делают. Чтобы этого избежать, сервер должен добавить в ответ соответствующие антикеш-заголовки, например .

Впрочем, использовать заголовки типа , и рекомендуется в любом случае, чтобы дать понять браузеру (не обязательно IE), что ему следует делать.

Альтернативный вариант – добавить в URL запроса случайный параметр, предотвращающий кеширование.

Например, вместо написать:

По историческим причинам такой способ предотвращения кеширования можно увидеть много где, так как старые браузеры плохо обрабатывали кеширующие заголовки. Сейчас серверные заголовки поддерживаются хорошо.

Установка и потеря фокуса

Теоретически, установить попап в фокус можно с помощью метода , а убрать из фокуса – с помощью . Также существуют события , которые позволяют отследить, когда фокус переводится на какое-то другое окно.

Раньше на «плохих» сайтах эти методы могли становиться средством манипуляции. Например:

Когда пользователь пытается перевести фокус на другое окно, этот код возвращает фокус назад. Таким образом, фокус как бы «блокируется» в попапе, который не нужен пользователю.

Из-за этого в браузерах и появились ограничения, которые препятствуют такого рода поведению фокуса. Эти ограничения нужны для защиты пользователя от назойливой рекламы и «плохих» страниц, и их работа различается в зависимости от конкретного браузера.

Например, мобильный браузер обычно полностью игнорирует такие вызовы метода . Также фокусировка не работает, когда попап открыт в отдельной вкладке (в отличие от открытия в отдельном окне).

Но все-таки иногда методы фокусировки бывают полезны. Например:

Когда мы открываем попап, может быть хорошей идеей запустить для него . Для некоторых комбинаций браузера и операционной системы это устранит неоднозначность – заметит ли пользователь это новое окно.
Если нужно отследить, когда посетитель использует веб-приложение, можно отслеживать . Это позволит ставить на паузу и продолжать выполнение анимаций и других интерактивных действий на странице

При этом важно помнить, что означает, что окно больше не в фокусе, но пользователь может по-прежнему видеть его.

Основы

XMLHttpRequest имеет два режима работы: синхронный и асинхронный.

Сначала рассмотрим асинхронный, так как в большинстве случаев используется именно он.

Чтобы сделать запрос, нам нужно выполнить три шага:

  1. Создать .

  2. Инициализировать его.

    Этот метод обычно вызывается сразу после . В него передаются основные параметры запроса:

    • – HTTP-метод. Обычно это или .
    • – URL, куда отправляется запрос: строка, может быть и объект URL.
    • – если указать , тогда запрос будет выполнен синхронно, это мы рассмотрим чуть позже.
    • , – логин и пароль для базовой HTTP-авторизации (если требуется).

    Заметим, что вызов , вопреки своему названию, не открывает соединение. Он лишь конфигурирует запрос, но непосредственно отсылается запрос только лишь после вызова .

  3. Послать запрос.

    Этот метод устанавливает соединение и отсылает запрос к серверу. Необязательный параметр содержит тело запроса.

    Некоторые типы запросов, такие как , не имеют тела. А некоторые, как, например, , используют , чтобы отправлять данные на сервер. Мы позже увидим примеры.

  4. Слушать события на , чтобы получить ответ.

    Три наиболее используемых события:

    • – происходит, когда получен какой-либо ответ, включая ответы с HTTP-ошибкой, например 404.
    • – когда запрос не может быть выполнен, например, нет соединения или невалидный URL.
    • – происходит периодически во время загрузки ответа, сообщает о прогрессе.

Вот полный пример. Код ниже загружает с сервера и сообщает о прогрессе:

После ответа сервера мы можем получить результат запроса в следующих свойствах :

Код состояния HTTP (число): , , и так далее, может быть в случае, если ошибка не связана с HTTP.
Сообщение о состоянии ответа HTTP (строка): обычно для , для , для , и так далее.
(в старом коде может встречаться как )
Тело ответа сервера.

Мы можем также указать таймаут – промежуток времени, который мы готовы ждать ответ:

Если запрос не успевает выполниться в установленное время, то он прерывается, и происходит событие .

URL с параметрами

Чтобы добавить к URL параметры, вида , и корректно закодировать их, можно использовать объект URL:

Полный синтаксис window.open

Полный синтаксис:

Функция возвращает ссылку на объект нового окна, либо , если окно было заблокировано браузером.

Параметры:

URL для загрузки в новое окно.
Имя нового окна. Может быть использовано в параметре в формах. Если позднее вызвать с тем же именем, то браузеры (кроме IE) заменяют существующее окно на новое.
Строка с конфигурацией для нового окна. Состоит из параметров, перечисленных через запятую. Пробелов в ней быть не должно.

Значения параметров .

  1. Настройки расположения окна:
(число)

Координаты верхнего левого угла относительно экрана. Ограничение: новое окно не может быть позиционировано за пределами экрана.

(число)

Ширина/высота нового окна. Минимальные значения ограничены, так что невозможно создать невидимое окно с нулевыми размерами.

Если координаты и размеры не указаны, то обычно браузер открывает не окно, а новую вкладку.

  1. Свойства окна:
(yes/no)
Скрыть или показать строку меню браузера.
(yes/no)
Показать или скрыть панель навигации браузера (кнопки назад, вперёд, обновить страницу и остальные) в новом окне.
(yes/no)
Показать/скрыть поле URL-адреса в новом окне. По умолчанию Firefox и IE не позволяют скрывать строку адреса.
(yes/no)
Показать или скрыть строку состояния. С другой стороны, браузер может в принудительном порядке показать строку состояния.
(yes/no)
Позволяет отключить возможность изменять размеры нового окна. Значение обычно неудобно посетителям.
(yes/no)
Разрешает убрать полосы прокрутки для нового окна. Значение обычно неудобно посетителям.
  1. Ещё есть небольшое количество не кросс-браузерных свойств, которые обычно не используются. Вы можете узнать о них в документации, например MDN: window.open.

Важно:

Браузер подходит к этим параметрам интеллектуально. Он может проигнорировать их часть или даже все, они скорее являются «пожеланиями», нежели «требованиями».

Важные моменты:

  • Если при вызове указан только первый параметр, параметр отсутствует, то используются параметры по умолчанию. Обычно при этом будет открыто не окно, а вкладка, что зачастую более удобно.
  • Если указана строка с параметрами, но некоторые параметры отсутствуют, то браузер выставляет их в . Поэтому убедитесь, что все нужные вам параметры выставлены в .
  • Когда не указан , то браузер откроет окно с небольшим смещением относительно левого верхнего угла последнего открытого окна.
  • Если не указаны , новое окно будет такого же размера, как последнее открытое.

Обмен сообщениями между окнами

Интерфейс позволяет окнам общаться между собой независимо от их происхождения.

Это способ обойти политику «Одинакового источника». Он позволяет обмениваться информацией, скажем и , но только в том случае, если оба сайта согласны и вызывают соответствующие JavaScript-функции. Это делает общение безопасным для пользователя.

Интерфейс имеет две части.

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

Аргументы:

Данные для отправки. Может быть любым объектом, данные клонируются с использованием «алгоритма структурированного клонирования». IE поддерживает только строки, поэтому мы должны использовать метод на сложных объектах, чтобы поддержать этот браузер.
Определяет источник для окна-получателя, только окно с данного источника имеет право получить сообщение.

Указание является мерой безопасности. Как мы помним, если окно (получатель) происходит из другого источника, мы из окна-отправителя не можем прочитать его . Таким образом, мы не можем быть уверены, какой сайт открыт в заданном окне прямо сейчас: пользователь мог перейти куда-то, окно-отправитель не может это знать.

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

Особенно это важно, если данные конфиденциальные

Например, здесь получит сообщения только в том случае, если в нём открыт документ из источника :

Если мы не хотим проверять, то в можно указать .

Чтобы получать сообщения, окно-получатель должно иметь обработчик события (сообщение). Оно срабатывает, когда был вызван метод (и проверка пройдена успешно).

Объект события имеет специфичные свойства:

Данные из .
Источник отправителя, например, .
Ссылка на окно-отправитель. Можно сразу отправить что-то в ответ, вызвав .

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

Вот пример:

Полный пример:

Результат
iframe.html
index.html

Без задержек

Между и событием не существует задержки. Событие происходит синхронно, быстрее, чем .

Ошибка в скрипте с другого источника

Есть правило: скрипты с одного сайта не могут получить доступ к содержимому другого сайта. Например, скрипт с не может прочитать почту пользователя на .

Или, если быть более точным, один источник (домен/порт/протокол) не может получить доступ к содержимому с другого источника. Даже поддомен или просто другой порт будут считаться разными источниками, не имеющими доступа друг к другу.

Это правило также касается ресурсов с других доменов.

Если мы используем скрипт с другого домена, и в нем имеется ошибка, мы не сможем узнать детали этой ошибки.

Для примера давайте возьмём мини-скрипт , который состоит из одного-единственного вызова функции, которой не существует:

Теперь загрузим этот скрипт с того же сайта, на котором он лежит:

Мы видим нормальный отчёт об ошибке:

А теперь загрузим этот же скрипт с другого домена:

Отчёт отличается:

Детали отчёта могут варьироваться в зависимости от браузера, но основная идея остаётся неизменной: любая информация о внутреннем устройстве скрипта, включая стек ошибки, спрятана. Именно потому, что скрипт загружен с другого домена.

Зачем нам могут быть нужны детали ошибки?

Существует много сервисов (и мы можем сделать наш собственный), которые обрабатывают глобальные ошибки при помощи , сохраняют отчёт о них и предоставляют доступ к этому отчёту для анализа. Это здорово, потому что мы можем увидеть реальные ошибки, которые случились у наших пользователей. Но если скрипт – с другого домена, то информации об ошибках в нём почти нет, как мы только что видели.

Похожая кросс-доменная политика (CORS) внедрена и в отношении других ресурсов.

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

Существует три уровня кросс-доменного доступа:

  1. Атрибут отсутствует – доступ запрещён.
  2. – доступ разрешён, если сервер отвечает с заголовком со значениями или наш домен. Браузер не отправляет авторизационную информацию и куки на удалённый сервер.
  3. – доступ разрешён, если сервер отвечает с заголовками со значением наш домен и . Браузер отправляет авторизационную информацию и куки на удалённый сервер.

Почитать больше о кросс-доменных доступах вы можете в главе Fetch: запросы на другие сайты. Там описан метод для сетевых запросов, но политика там точно такая же.

Такое понятие как «куки» (cookies) не рассматривается в текущей главе, но вы можете почитать о них в главе Куки, document.cookie.

В нашем случае атрибут отсутствовал. Поэтому кросс-доменный доступ был запрещён. Давайте добавим его.

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

Если куки нас не волнуют, тогда смело выбираем :

Теперь при условии, что сервер предоставил заголовок , всё хорошо. У нас есть полный отчёт по ошибкам.

Подробно о window.onload

  1. Иногда, происходит такое, что вы, вроде бы и написали все правильно, но скрипт… просто не работает. И непонятно почему.

    Одна из причин — это загрузка скрипта раньше, чем самой страницы. Ваш скрипт — тупо не видит код ниже себя.

    Для этого существует window.onload

    window — объект.

    onload — это «событие». Иногда, на просторах интернета можно встретить разное название для этого события, но «onload» — это «Event», а в переводе — это событие.

    Использовать window.onload можно самым простым способом, размещаем данный скрипт на странице и после загрузки страницы, вы увидите сообщение о том «скрипт выполнился после загрузки страницы»

    <script>

    window.onload = function() {

    alert(‘Страница загружена’);

    };

    </script>

    Если у вас подключенный скрипт, то теги <script> и </script> не нужны.

    window.onload = function() {

    здесь помещаем все, что угодно…

    };

    object может быть например body или window, естественно к этому объекту, сперва нужно обратиться.

    object.onload=function(){/**код**/};

    В качестве атрибута onload, возможно использование в HTML :

    <element onload=»myFunction»></element>

  2. Давайте попробуем создать эмуляцию window.onload, как это работает в реальном времени.

    Создадим скрипт и разместим его тут на странице:

    <script>

    window.onload = function() {

    alert(‘Страница загружена’);

    // к этому моменту страница загружена

    alert(`Image size: ${img.offsetWidth}x${img.offsetHeight}`);

    };

    </script>

    <img id=»img» src=»https://dwweb.ru/__a-data/__all_for_scripts/__examples/js/onload/onload.jpg»>

    Нажмите кнопку window.onload :
    window.onload

  3. Несколько вариантов для запуска вашего скрипта, при использовании JQuery

    $(window).load(function() {

    /** код запустится, когда страница будет полностью загружена на 100% **/

    });

    +

    //Вариант 1

    $(document).ready(function() {

    /** код запустится, когда будет готов DOM, исключая картинки **/

    // ваш код

    });

    //Вариант 2

    $(function() {

    /** код запустится, когда будет готов DOM, исключая картинки **/

    //ваш код

    });

    //Вариант 3

    $(document).on(‘ready’, function(){

    /** код запустится, когда будет готов DOM, исключая картинки **/

    //ваш код

    });

    //Вариант 4

    jQuery(document).ready(function(){

    /** код запустится, когда будет готов DOM, исключая картинки **/

    //ваш код

    });

    И!
    Не путаете window load jQuery с методом .

Последняя дата редактирования : 22.01.2021 00:06
//dwweb.ru/comments_1_5/include/img/hand_no_foto.png
no
no

Код кроссбраузерной поддержки

«Родное» событие есть не во всех браузерах, поэтому мы рассмотрим код для кроссбраузерной поддержки этого события:

function bindReady(handler){

	var called = false

	function ready() { // (1)
		if (called) return
		called = true
		handler()
	}

	if ( document.addEventListener ) { // (2)
		document.addEventListener( "DOMContentLoaded", function(){
			ready()
		}, false )
	} else if ( document.attachEvent ) {  // (3)

		// (3.1)
		if ( document.documentElement.doScroll && window == window.top ) {
			function tryScroll(){
				if (called) return
				if (!document.body) return
				try {
					document.documentElement.doScroll("left")
					ready()
				} catch(e) {
					setTimeout(tryScroll, 0)
				}
			}
			tryScroll()
		}

		// (3.2)
		document.attachEvent("onreadystatechange", function(){

			if ( document.readyState === "complete" ) {
				ready()
			}
		})
	}

	// (4)
    if (window.addEventListener)
        window.addEventListener('load', ready, false)
    else if (window.attachEvent)
        window.attachEvent('onload', ready)
    /*  else  // (4.1)
        window.onload=ready
	*/
}

Разберем его по шагам.

  1. Код будет пытаться поймать событие различными способами. Вполне может получиться так, что несколько способов сработают независимо.

    Поэтому завернем обработчик в функцию , единственный смысл которой — гарантировать, что будет вызван не более одного раза.

  2. Событие поддерживают достаточно новые Firefox, Opera, Safari/Chrome. Нет гарантии, что версия посетителя поддерживает это событие, но попробовать стоит.
  3. Браузер Internet Explorer не поддерживает , поэтому для него используются обходные пути.
    1. Функция пытается скроллить документ вызовом . Если получается — значит, документ загрузился, если нет — заказывает повторную попытку через setTimeout, и так пока документ наконец не будет готов. На практике это очень надежный способ, но есть проблемы с фреймами, поэтому используется только для окон верхнего уровня.
      Дополнительный фильтр — проверка
    2. Событие с проверкой , как и , срабатывает после загрузки документа. Но, к сожалению, оно происходит уже после загрузки картинок. Поэтому — вообще говоря, не то, что нам надо. Но это событие работает для фреймов, и при этом срабатывает до . Поэтому будем использовать и этот способ.
  4. Для тех браузеров, в которых не сработали предыдущие методы (например, очень старый Firefox), добавим вызов обработчика при событии .
    1. Для совсем древних браузеров, в которых нет , вы можете раскомментировать и строчку (4.1). При этом, разумеется, возможен конфликт с другими обработчиками .

Этот код взят, с небольшими упрощениями, из библиотеки jQuery, а методы придуманы различными авторами.

Переход внутрь ифрейма

В примере ниже JavaScript получает документ внутри ифрейма и модифицирует его:

src=„javascript:«текст»“

Атрибут может использовать протокол , как указано выше: . При этом код выполняется и его результат будет содержимым ифрейма. Этот способ описан в стандарте и поддерживается всеми браузерами.

Атрибут является обязательным, и его отсутствие может привести к проблемам, вплоть до игнорирования ифрейма браузером. Чтобы ничего не загружать в ифрейм, можно указать пустую строку: или специальную страницу: .

В некоторых браузерах (Chrome) пример выше покажет зелёным. А в некоторых (Firefox) – оранжевым.

Дело в том, что, когда только создан, документ в нём обычно ещё не загружен.

При обычных значениях , которые указывают на HTML-страницу (даже если она уже в кеше), это всегда так. Документ, который в на момент срабатывания скрипта – временный, он будет заменён на новый очень скоро. И работать надо уже с новым документом – например, по событию .

В случае с -протоколом, по идее, ифрейм уже загружен, и тогда у него уже не будет. Но здесь мнения браузеров расходятся, некоторые (Firefox) всё равно «подгрузят» документ позже. Поэтому факт «готовности» документа в скрипте проверяется через .

Ещё раз заметим, что при обычных URL в качестве нужно работать не с начальным документом, а с тем, который появится позже.

More Examples

Example

Using onload on an <img> element. Alert «Image is loaded» immediately after
an image has been loaded:

<img src=»w3javascript.gif» onload=»loadImage()» width=»100″ height=»132″><script>function loadImage() {  alert(«Image is loaded»);}
</script>

Example

Using the onload event to deal with cookies:

<body onload=»checkCookies()»><script>
function checkCookies() {  var text = «»;  if (navigator.cookieEnabled == true) {    text = «Cookies are enabled.»;  } else {     text = «Cookies are not enabled.»;
  }  document.getElementById(«demo»).innerHTML = text;}</script>

❮ DOM Events
❮ Event Object

What About Chaining The Functions?

One method that has been used quite a bit is the linking of multiple events. It places several function calls in a chain, using one onload event handler.

The method would look like this:

<body onload="functionA(); functionB();">

Again, this wouldn’t be unobtrusive JavaScript. You would also need to add all the functions that need access to the onload method to the body tag of every page. For a large website, this would be too tedious and too difficult to maintain.

Some developers have also used code structures like this:

function start() {
  functionA();
  functionB();
}
window.onload = start;

While this looks like a good fix, think of a scenario where you don’t have access to control where one of the functions is called (it could be called in a third party plugin for example).

HTML Reference

HTML by AlphabetHTML by CategoryHTML Browser SupportHTML AttributesHTML Global AttributesHTML EventsHTML ColorsHTML CanvasHTML Audio/VideoHTML Character SetsHTML DoctypesHTML URL EncodeHTML Language CodesHTML Country CodesHTTP MessagesHTTP MethodsPX to EM ConverterKeyboard Shortcuts

HTML Tags

<!—>
<!DOCTYPE>
<a>
<abbr>
<acronym>
<address>
<applet>
<area>
<article>
<aside>
<audio>
<b>
<base>
<basefont>
<bdi>
<bdo>
<big>
<blockquote>
<body>
<br>
<button>
<canvas>
<caption>
<center>
<cite>
<code>
<col>
<colgroup>
<data>
<datalist>
<dd>
<del>
<details>
<dfn>
<dialog>
<dir>
<div>
<dl>
<dt>
<em>
<embed>
<fieldset>
<figcaption>
<figure>
<font>
<footer>
<form>
<frame>
<frameset>
<h1> — <h6>
<head>
<header>
<hr>
<html>
<i>
<iframe>
<img>
<input>
<ins>
<kbd>
<label>
<legend>
<li>
<link>
<main>
<map>
<mark>
<meta>
<meter>
<nav>
<noframes>
<noscript>
<object>
<ol>
<optgroup>
<option>
<output>
<p>
<param>
<picture>
<pre>
<progress>
<q>
<rp>
<rt>
<ruby>
<s>
<samp>
<script>
<section>
<select>
<small>
<source>
<span>
<strike>
<strong>
<style>
<sub>
<summary>
<sup>
<svg>
<table>
<tbody>
<td>
<template>
<textarea>
<tfoot>
<th>
<thead>
<time>
<title>
<tr>
<track>
<tt>
<u>
<ul>
<var>
<video>
<wbr>

Событие onprogress в деталях

При обработке события onprogress есть ряд важных тонкостей.

Заметим, что событие, возникающее при onprogress, имеет одинаковый вид на стадии закачки (в обработчике xhr.upload.onprogress) и при получении ответа (в обработчике xhr.onprogress).

Оно представляет  объект типа ProgressEvent со свойствами:

loaded
Сколько байт уже переслано.

Имеется в виду только тело запроса, заголовки не учитываются.

lengthComputable
Если true, то известно полное количество байт для пересылки, и оно хранится в свойстве total.
total
Общее количество байт для пересылки, если известно.

А может ли оно быть неизвестно?

  • При закачке на сервер браузер всегда знает полный размер пересылаемых данных, так что total всегда содержит конкретное количество байт, а значение lengthComputable всегда будет true.
  • При скачивании данных – обычно сервер в начале сообщает их общее количество в HTTP-заголовке Content-Length. Но он может и не делать этого, например если сам не знает, сколько данных будет или если генерирует их динамически. Тогда total будет равно нулю. А чтобы отличить нулевой размер данных от неизвестного – как раз служит lengthComputable, которое в данном случае равно false.

Ещё особенности, которые необходимо учитывать при использовании onprogress:

Событие происходит при каждом полученном/отправленном байте, но не чаще чем раз в 50 мс.Это обозначено в спецификации progress notifications.
В процессе получения данных, ещё до их полной передачи, доступен xhr.responseText, но он не обязательно содержит корректную строку.Можно до окончания запроса заглянуть в него и прочитать текущие полученные данные

Важно, что при пересылке строки в кодировке UTF-8 кириллические символы, как, впрочем, и многие другие, кодируются 2 байтами. Возможно, что в конце одного пакета данных окажется первая половинка символа, а в начале следующего – вторая

Поэтому полагаться на то, что до окончания запроса в responseText находится корректная строка нельзя. Она может быть обрезана посередине символа.Исключение – заведомо однобайтные символы, например цифры или латиница.
Сработавшее событие xhr.upload.onprogress не гарантирует, что данные дошли.Событие xhr.upload.onprogress срабатывает, когда данные отправлены браузером. Но оно не гарантирует, что сервер получил, обработал и записал данные на диск. Он говорит лишь о самом факте отправки.Поэтому прогресс-индикатор, получаемый при его помощи, носит приблизительный и оптимистичный характер.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector