Onload
Содержание:
- Обмен сообщениями между окнами
- Загрузка скриптов
- Crossorigin policy
- Полный синтаксис window.open
- Основы
- Example HTML code 2:
- Установка и потеря фокуса
- More Examples
- Другие ресурсы
- Пример: минималистичное окно
- Как работает HTTP, и зачем нам это знать
- Событие onprogress в деталях
- Переход внутрь ифрейма
- Код кроссбраузерной поддержки
- HTTP-заголовки
- Итого
- Итого
- Итого
Обмен сообщениями между окнами
Интерфейс позволяет окнам общаться между собой независимо от их происхождения.
Это способ обойти политику «Одинакового источника». Он позволяет обмениваться информацией, скажем и , но только в том случае, если оба сайта согласны и вызывают соответствующие JavaScript-функции. Это делает общение безопасным для пользователя.
Интерфейс имеет две части.
Окно, которое хочет отправить сообщение, должно вызвать метод postMessage окна получателя. Другими словами, если мы хотим отправить сообщение в окно , тогда нам следует вызвать .
Аргументы:
- Данные для отправки. Может быть любым объектом, данные клонируются с использованием «алгоритма структурированного клонирования». IE поддерживает только строки, поэтому мы должны использовать метод на сложных объектах, чтобы поддержать этот браузер.
- Определяет источник для окна-получателя, только окно с данного источника имеет право получить сообщение.
Указание является мерой безопасности. Как мы помним, если окно (получатель) происходит из другого источника, мы из окна-отправителя не можем прочитать его . Таким образом, мы не можем быть уверены, какой сайт открыт в заданном окне прямо сейчас: пользователь мог перейти куда-то, окно-отправитель не может это знать.
Если указать , то мы можем быть уверены, что окно получит данные только в том случае, если в нём правильный сайт
Особенно это важно, если данные конфиденциальные
Например, здесь получит сообщения только в том случае, если в нём открыт документ из источника :
Если мы не хотим проверять, то в можно указать .
Чтобы получать сообщения, окно-получатель должно иметь обработчик события (сообщение). Оно срабатывает, когда был вызван метод (и проверка пройдена успешно).
Объект события имеет специфичные свойства:
- Данные из .
- Источник отправителя, например, .
- Ссылка на окно-отправитель. Можно сразу отправить что-то в ответ, вызвав .
Чтобы добавить обработчик, следует использовать метод , короткий синтаксис не работает.
Вот пример:
Полный пример:
Результат
iframe.html
index.html
Без задержек
Между и событием не существует задержки. Событие происходит синхронно, быстрее, чем .
Загрузка скриптов
Допустим, нам нужно загрузить сторонний скрипт и вызвать функцию, которая объявлена в этом скрипте.
Мы можем загрузить этот скрипт динамически:
let script = document.createElement('script'); script.src = "my.js"; document.head.append(script);
…Но как нам вызвать функцию, которая объявлена внутри того скрипта? Нам нужно подождать, пока скрипт загрузится, и только потом мы можем её вызвать.
script.onload
Главный помощник — это событие . Оно срабатывает после того, как скрипт был загружен и выполнен.
Например:
let script = document.createElement('script'); // мы можем загрузить любой скрипт с любого домена script.src = "https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.3.0/lodash.js" document.head.append(script); *!* script.onload = function() { // в скрипте создаётся вспомогательная функция с именем "_" alert(_); // функция доступна }; *!*
Таким образом, в обработчике мы можем использовать переменные, вызывать функции и т.д., которые предоставляет нам сторонний скрипт.
…А что если во время загрузки произошла ошибка? Например, такого скрипта нет (ошибка 404), или сервер был недоступен.
script.onerror
Ошибки, которые возникают во время загрузки скрипта, могут быть отслежены с помощью события .
Например, давайте запросим скрипт, которого не существует:
let script = document.createElement('script'); script.src = "https://example.com/404.js"; // такого файла не существует document.head.append(script); *!* script.onerror = function() { alert("Error loading " + this.src); // Ошибка загрузки https://example.com/404.js }; *!*
Обратите внимание, что мы не можем получить описание HTTP-ошибки. Мы не знаем, была ли это ошибка 404 или 500, или какая-то другая
Знаем только, что во время загрузки произошла ошибка.
Crossorigin policy
There’s a rule: scripts from one site can’t access contents of the other site. So, e.g. a script at can’t read the user’s mailbox at .
Or, to be more precise, one origin (domain/port/protocol triplet) can’t access the content from another one. So even if we have a subdomain, or just another port, these are different origins with no access to each other.
This rule also affects resources from other domains.
If we’re using a script from another domain, and there’s an error in it, we can’t get error details.
For example, let’s take a script that consists of a single (bad) function call:
Now load it from the same site where it’s located:
We can see a good error report, like this:
Now let’s load the same script from another domain:
The report is different, like this:
Details may vary depending on the browser, but the idea is the same: any information about the internals of a script, including error stack traces, is hidden. Exactly because it’s from another domain.
Why do we need error details?
There are many services (and we can build our own) that listen for global errors using , save errors and provide an interface to access and analyze them. That’s great, as we can see real errors, triggered by our users. But if a script comes from another origin, then there’s not much information about errors in it, as we’ve just seen.
Similar cross-origin policy (CORS) is enforced for other types of resources as well.
To allow cross-origin access, the tag needs to have the attribute, plus the remote server must provide special headers.
There are three levels of cross-origin access:
- No attribute – access prohibited.
- – access allowed if the server responds with the header with or our origin. Browser does not send authorization information and cookies to remote server.
- – access allowed if the server sends back the header with our origin and . Browser sends authorization information and cookies to remote server.
Please note:
You can read more about cross-origin access in the chapter Fetch: Cross-Origin Requests. It describes the method for network requests, but the policy is exactly the same.
Such thing as “cookies” is out of our current scope, but you can read about them in the chapter Cookies, document.cookie.
In our case, we didn’t have any crossorigin attribute. So the cross-origin access was prohibited. Let’s add it.
We can choose between (no cookies sent, one server-side header needed) and (sends cookies too, two server-side headers needed).
If we don’t care about cookies, then is the way to go:
Now, assuming that the server provides an header, everything’s fine. We have the full error report.
Полный синтаксис window.open
Полный синтаксис:
Функция возвращает ссылку на объект нового окна, либо , если окно было заблокировано браузером.
Параметры:
- URL для загрузки в новое окно.
- Имя нового окна. Может быть использовано в параметре в формах. Если позднее вызвать с тем же именем, то браузеры (кроме IE) заменяют существующее окно на новое.
- Строка с конфигурацией для нового окна. Состоит из параметров, перечисленных через запятую. Пробелов в ней быть не должно.
Значения параметров .
- Настройки расположения окна:
- (число)
-
Координаты верхнего левого угла относительно экрана. Ограничение: новое окно не может быть позиционировано за пределами экрана.
- (число)
-
Ширина/высота нового окна. Минимальные значения ограничены, так что невозможно создать невидимое окно с нулевыми размерами.
Если координаты и размеры не указаны, то обычно браузер открывает не окно, а новую вкладку.
- Свойства окна:
- (yes/no)
- Скрыть или показать строку меню браузера.
- (yes/no)
- Показать или скрыть панель навигации браузера (кнопки назад, вперёд, обновить страницу и остальные) в новом окне.
- (yes/no)
- Показать/скрыть поле URL-адреса в новом окне. По умолчанию Firefox и IE не позволяют скрывать строку адреса.
- (yes/no)
- Показать или скрыть строку состояния. С другой стороны, браузер может в принудительном порядке показать строку состояния.
- (yes/no)
- Позволяет отключить возможность изменять размеры нового окна. Значение обычно неудобно посетителям.
- (yes/no)
- Разрешает убрать полосы прокрутки для нового окна. Значение обычно неудобно посетителям.
- Ещё есть небольшое количество не кросс-браузерных свойств, которые обычно не используются. Вы можете узнать о них в документации, например MDN: window.open.
Важно:
Браузер подходит к этим параметрам интеллектуально. Он может проигнорировать их часть или даже все, они скорее являются «пожеланиями», нежели «требованиями».
Важные моменты:
- Если при вызове указан только первый параметр, параметр отсутствует, то используются параметры по умолчанию. Обычно при этом будет открыто не окно, а вкладка, что зачастую более удобно.
- Если указана строка с параметрами, но некоторые параметры отсутствуют, то браузер выставляет их в . Поэтому убедитесь, что все нужные вам параметры выставлены в .
- Когда не указан , то браузер откроет окно с небольшим смещением относительно левого верхнего угла последнего открытого окна.
- Если не указаны , новое окно будет такого же размера, как последнее открытое.
Основы
XMLHttpRequest имеет два режима работы: синхронный и асинхронный.
Сначала рассмотрим асинхронный, так как в большинстве случаев используется именно он.
Чтобы сделать запрос, нам нужно выполнить три шага:
-
Создать .
-
Инициализировать его.
Этот метод обычно вызывается сразу после . В него передаются основные параметры запроса:
- – HTTP-метод. Обычно это или .
- – URL, куда отправляется запрос: строка, может быть и объект URL.
- – если указать , тогда запрос будет выполнен синхронно, это мы рассмотрим чуть позже.
- , – логин и пароль для базовой HTTP-авторизации (если требуется).
Заметим, что вызов , вопреки своему названию, не открывает соединение. Он лишь конфигурирует запрос, но непосредственно отсылается запрос только лишь после вызова .
-
Послать запрос.
Этот метод устанавливает соединение и отсылает запрос к серверу. Необязательный параметр содержит тело запроса.
Некоторые типы запросов, такие как , не имеют тела. А некоторые, как, например, , используют , чтобы отправлять данные на сервер. Мы позже увидим примеры.
-
Слушать события на , чтобы получить ответ.
Три наиболее используемых события:
- – происходит, когда получен какой-либо ответ, включая ответы с HTTP-ошибкой, например 404.
- – когда запрос не может быть выполнен, например, нет соединения или невалидный URL.
- – происходит периодически во время загрузки ответа, сообщает о прогрессе.
Вот полный пример. Код ниже загружает с сервера и сообщает о прогрессе:
После ответа сервера мы можем получить результат запроса в следующих свойствах :
- Код состояния HTTP (число): , , и так далее, может быть в случае, если ошибка не связана с HTTP.
- Сообщение о состоянии ответа HTTP (строка): обычно для , для , для , и так далее.
- (в старом коде может встречаться как )
- Тело ответа сервера.
Мы можем также указать таймаут – промежуток времени, который мы готовы ждать ответ:
Если запрос не успевает выполниться в установленное время, то он прерывается, и происходит событие .
URL с параметрами
Чтобы добавить к URL параметры, вида , и корректно закодировать их, можно использовать объект URL:
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 |
Установка и потеря фокуса
Теоретически, установить попап в фокус можно с помощью метода , а убрать из фокуса – с помощью . Также существуют события , которые позволяют отследить, когда фокус переводится на какое-то другое окно.
Раньше на «плохих» сайтах эти методы могли становиться средством манипуляции. Например:
Когда пользователь пытается перевести фокус на другое окно, этот код возвращает фокус назад. Таким образом, фокус как бы «блокируется» в попапе, который не нужен пользователю.
Из-за этого в браузерах и появились ограничения, которые препятствуют такого рода поведению фокуса. Эти ограничения нужны для защиты пользователя от назойливой рекламы и «плохих» страниц, и их работа различается в зависимости от конкретного браузера.
Например, мобильный браузер обычно полностью игнорирует такие вызовы метода . Также фокусировка не работает, когда попап открыт в отдельной вкладке (в отличие от открытия в отдельном окне).
Но все-таки иногда методы фокусировки бывают полезны. Например:
Когда мы открываем попап, может быть хорошей идеей запустить для него . Для некоторых комбинаций браузера и операционной системы это устранит неоднозначность – заметит ли пользователь это новое окно.
Если нужно отследить, когда посетитель использует веб-приложение, можно отслеживать . Это позволит ставить на паузу и продолжать выполнение анимаций и других интерактивных действий на странице
При этом важно помнить, что означает, что окно больше не в фокусе, но пользователь может по-прежнему видеть его.
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
Другие ресурсы
События и также срабатывают и для других ресурсов, а вообще, для любых ресурсов, у которых есть внешний .
Например:
let img = document.createElement('img'); img.src = "https://js.cx/clipart/train.gif"; // (*) img.onload = function() { alert(`Изображение загружено, размеры ${img.width}x${img.height}`); }; img.onerror = function() { alert("Ошибка во время загрузки изображения"); };
Однако есть некоторые особенности:
- Большинство ресурсов начинают загружаться после их добавления в документ. За исключением тега . Изображения начинают загружаться, когда получают .
- Для событие срабатывает по окончании загрузки как в случае успеха, так и в случае ошибки.
Такое поведение сложилось по историческим причинам.
Пример: минималистичное окно
Давайте откроем окно с минимальным набором настроек, просто чтобы посмотреть, какие из них браузер позволит отключить:
В этом примере большинство настроек заблокированы и само окно находится за пределами видимой области экрана. Посмотрим, что получится в результате. Большинство браузеров «исправит» странные значения – как, например, нулевые и отрицательные . Например, Chrome установит высоту и ширину такого окна равной высоте и ширине экрана, так что попап будет занимать весь экран.
Давайте исправим значения и зададим нормальные координаты ( и ) и значения размеров окна ( и ):
Большинство браузеров выведет окно с заданными нами настройками.
Правила для опущенных параметров:
- Если третий аргумент при вызове отсутствует или он пустой, будут использованы настройки окна по умолчанию.
- Если строка параметров передана, но некоторые параметры yes/no пропущены, то считается, что указано , так что соответствующие возможности будут отключены, если на это нет ограничений со стороны браузера. Поэтому при задании параметров убедитесь, что вы явно указали все необходимые yes.
- Если координаты не заданы, браузер попытается открыть новое окно рядом с предыдущим открытым окном.
- Если не заданы размеры окна , браузер откроет новое окно с теми же размерами, что и предыдущее открытое окно.
Как работает HTTP, и зачем нам это знать
Программировать на PHP можно и без знания протокола HTTP, но есть ряд ситуаций, когда для решения задач нужно знать, как именно работает веб-сервер. Ведь PHP — это, в первую очередь, серверный язык программирования.
Протокол HTTP очень прост и состоит, по сути, из двух частей:
- Заголовков запроса/ответа;
- Тела запроса/ответа.
Сначала идёт список заголовков, затем пустая строка, а затем (если есть) тело запроса/ответа.
И клиент, и сервер могут посылать друг другу заголовки и тело ответа, но в случае с клиентом доступные заголовки будут одни, а с сервером — другие. Рассмотрим пошагово, как будет выглядеть работа по протоколу HTTP в случае, когда пользователь хочет загрузить главную страницу социальной сети «Вконтакте».
1. Браузер пользователя устанавливает соединение с сервером vk.com и отправляет следующий запрос:
GET / HTTP/1.1 Host: vk.com
2. Сервер принимает запрос и отправляет ответ:
3. Браузер принимает ответ и показывает готовую страницу
Больше всего нам интересен самый первый шаг, где браузер инициирует запрос к серверу vk.com
Рассмотрим подробнее, что там происходит. Первая строка запроса определяет несколько важных параметров, а именно:
- Метод, которым будет запрошен контент;
- Адрес страницы;
- Версию протокола.
— это метод (глагол), который мы применяем для доступа к указанной странице. является самым часто используемым методом, потому что он говорит серверу о том, что клиент всего лишь хочет прочитать указанный документ. Но помимо есть и другие методы, один из них мы рассмотрим уже в следующем разделе.
После метода идет указание на адрес страницы — URI (универсальный идентификатор ресурса). В нашем случае мы запрашиваем главную страницу сайта, поэтому используется просто слэш — .
Последним в этой строке идет версия протокола и почти всегда это будет
После строки с указанием основных параметров всегда следует перечисление заголовков, которые передают серверу дополнительную полезную информацию: название и версию браузера, язык, кодировку, параметры кэширования и так далее.
Среди всех этих заголовков, которые передаются при каждом запросе, есть один обязательный и самый важный — это заголовок . Он определяет адрес домена, который запрашивает браузер клиента.
Сервер, получив запрос, ищет у себя сайт с доменом из заголовка , а также указанную страницу.
Если запрошенный сайт и страница найдены, клиенту отправляется ответ:
Такой ответ означает, что всё хорошо, документ найден и будет отправлен клиенту. Если говорить более обобщённо, стартовая строка ответа имеет следующую структуру:
Больше всего здесь интересен именно код состояния, он же код ответа сервера.
В этом примере код ответа — 200, что означает: сервер работает, документ найден и будет передан клиенту. Но не всегда всё идет гладко.
Например, запрошенный документ может отсутствовать или сервер будет перегружен, в таком случае клиент не получит контент, а код ответа будет отличным от 200.
- 404 — если сервер доступен, но запрошённый документ не найден;
- 503 — если сервер не может обрабатывать запросы по техническим причинам.
Спецификация HTTP 1.1 определяет 40 различных кодов HTTP.
После стартовой строки следуют заголовки, а затем тело ответа.
Событие 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 срабатывает, когда данные отправлены браузером. Но оно не гарантирует, что сервер получил, обработал и записал данные на диск. Он говорит лишь о самом факте отправки.Поэтому прогресс-индикатор, получаемый при его помощи, носит приблизительный и оптимистичный характер.
Переход внутрь ифрейма
В примере ниже JavaScript получает документ внутри ифрейма и модифицирует его:
src=„javascript:«текст»“
Атрибут может использовать протокол , как указано выше: . При этом код выполняется и его результат будет содержимым ифрейма. Этот способ описан в стандарте и поддерживается всеми браузерами.
Атрибут является обязательным, и его отсутствие может привести к проблемам, вплоть до игнорирования ифрейма браузером. Чтобы ничего не загружать в ифрейм, можно указать пустую строку: или специальную страницу: .
В некоторых браузерах (Chrome) пример выше покажет зелёным. А в некоторых (Firefox) – оранжевым.
Дело в том, что, когда только создан, документ в нём обычно ещё не загружен.
При обычных значениях , которые указывают на HTML-страницу (даже если она уже в кеше), это всегда так. Документ, который в на момент срабатывания скрипта – временный, он будет заменён на новый очень скоро. И работать надо уже с новым документом – например, по событию .
В случае с -протоколом, по идее, ифрейм уже загружен, и тогда у него уже не будет. Но здесь мнения браузеров расходятся, некоторые (Firefox) всё равно «подгрузят» документ позже. Поэтому факт «готовности» документа в скрипте проверяется через .
Ещё раз заметим, что при обычных URL в качестве нужно работать не с начальным документом, а с тем, который появится позже.
Код кроссбраузерной поддержки
«Родное» событие есть не во всех браузерах, поэтому мы рассмотрим код для кроссбраузерной поддержки этого события:
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 */ }
Разберем его по шагам.
- Код будет пытаться поймать событие различными способами. Вполне может получиться так, что несколько способов сработают независимо.
Поэтому завернем обработчик в функцию , единственный смысл которой — гарантировать, что будет вызван не более одного раза.
- Событие поддерживают достаточно новые Firefox, Opera, Safari/Chrome. Нет гарантии, что версия посетителя поддерживает это событие, но попробовать стоит.
- Браузер Internet Explorer не поддерживает , поэтому для него используются обходные пути.
- Функция пытается скроллить документ вызовом . Если получается — значит, документ загрузился, если нет — заказывает повторную попытку через setTimeout, и так пока документ наконец не будет готов. На практике это очень надежный способ, но есть проблемы с фреймами, поэтому используется только для окон верхнего уровня.
Дополнительный фильтр — проверка - Событие с проверкой , как и , срабатывает после загрузки документа. Но, к сожалению, оно происходит уже после загрузки картинок. Поэтому — вообще говоря, не то, что нам надо. Но это событие работает для фреймов, и при этом срабатывает до . Поэтому будем использовать и этот способ.
- Функция пытается скроллить документ вызовом . Если получается — значит, документ загрузился, если нет — заказывает повторную попытку через setTimeout, и так пока документ наконец не будет готов. На практике это очень надежный способ, но есть проблемы с фреймами, поэтому используется только для окон верхнего уровня.
- Для тех браузеров, в которых не сработали предыдущие методы (например, очень старый Firefox), добавим вызов обработчика при событии .
- Для совсем древних браузеров, в которых нет , вы можете раскомментировать и строчку (4.1). При этом, разумеется, возможен конфликт с другими обработчиками .
Этот код взят, с небольшими упрощениями, из библиотеки jQuery, а методы придуманы различными авторами.
HTTP-заголовки
умеет как указывать свои заголовки в запросе, так и читать присланные в ответ.
Для работы с HTTP-заголовками есть 3 метода:
-
Устанавливает заголовок запроса с именем и значением .
Например:
Ограничения на заголовки
Некоторые заголовки управляются исключительно браузером, например или , а также ряд других.
Полный список .не разрешено изменять их ради безопасности пользователей и для обеспечения корректности HTTP-запроса.
Поставленный заголовок нельзя снять
Ещё одной особенностью является то, что отменить невозможно.
Если заголовок определён, то его нельзя снять. Повторные вызовы лишь добавляют информацию к заголовку, а не перезаписывают его.
Например:
-
Возвращает значение заголовка ответа (кроме и ).
Например:
-
Возвращает все заголовки ответа, кроме и .
Заголовки возвращаются в виде единой строки, например:
Между заголовками всегда стоит перевод строки в два символа (независимо от ОС), так что мы можем легко разделить их на отдельные заголовки. Значение заголовка всегда отделено двоеточием с пробелом . Этот формат задан стандартом.
Таким образом, если хочется получить объект с парами заголовок-значение, нам нужно задействовать немного JS.
Вот так (предполагается, что если два заголовка имеют одинаковое имя, то последний перезаписывает предыдущий):
Итого
Чтобы вызвать метод или получить содержимое из другого окна, нам, во-первых, необходимо иметь ссылку на него.
Для всплывающих окон (попапов) доступны ссылки в обе стороны:
- При открытии окна: открывает новое окно и возвращает ссылку на него,
- Изнутри открытого окна: – ссылка на открывающее окно.
Для ифреймов мы можем иметь доступ к родителям/потомкам, используя:
- – коллекция объектов вложенных ифреймов,
- , – это ссылки на родительское окно и окно самого верхнего уровня,
- – это объект внутри тега .
Если окна имеют одинаковый источник (протокол, домен, порт), то они могут делать друг с другом всё, что угодно.
В противном случае возможны только следующие действия:
- Изменение свойства location другого окна (доступ только на запись).
- Отправить туда сообщение.
Исключения:
- Окна, которые имеют общий домен второго уровня: и . Установка свойства в обоих окнах переведёт их в состояние «Одинакового источника».
- Если у ифрейма установлен атрибут , это принудительно переведёт окна в состояние «разных источников», если не установить в атрибут значение . Это можно использовать для запуска ненадёжного кода в ифрейме с того же сайта.
Метод позволяет общаться двум окнам с любыми источниками:
-
Отправитель вызывает .
-
Если не , тогда браузер проверяет имеет ли источник .
-
Если это так, тогда вызывает событие со специальными свойствами:
- – источник окна отправителя (например, )
- – ссылка на окно отправитель.
- – данные, может быть объектом везде, кроме IE (в IE только строки).
В окне-получателе следует добавить обработчик для этого события с помощью метода .
Итого
Говоря о стандартах, у нас есть:
- Спецификация DOM
- описывает структуру документа, манипуляции с контентом и события, подробнее на https://dom.spec.whatwg.org.
- Спецификация CSSOM
- Описывает файлы стилей, правила написания стилей и манипуляций с ними, а также то, как это всё связано со страницей, подробнее на https://www.w3.org/TR/cssom-1/.
- Спецификация HTML
- Описывает язык HTML (например, теги) и BOM (объектную модель браузера) – разные функции браузера: , , и так далее, подробнее на https://html.spec.whatwg.org. Тут берётся за основу спецификация DOM и расширяется дополнительными свойствами и методами.
Кроме того, некоторые классы описаны отдельно на https://spec.whatwg.org/.
Пожалуйста, заметьте для себя эти ссылки, так как по ним содержится очень много информации, которую невозможно изучить полностью и держать в уме.
Когда вам нужно будет прочитать о каком-то свойстве или методе, справочник на сайте Mozilla https://developer.mozilla.org/ru/search тоже очень хороший ресурс, хотя ничто не сравнится с чтением спецификации: она сложная и объёмная, но сделает ваши знания максимально полными.
Для поиска чего-либо обычно удобно использовать интернет-поиск со словами «WHATWG » или «MDN », например https://google.com?q=whatwg+localstorage, https://google.com?q=mdn+localstorage.
А теперь давайте перейдём к изучению DOM, так как страница – это основа всего.
Итого
Типичный код GET-запроса с использованием :
Событий на самом деле больше, в они все перечислены в том порядке, в каком генерируются во время запроса:
- – начало запроса.
- – прибыла часть данных ответа, тело ответа полностью на данный момент можно получить из свойства .
- – запрос был прерван вызовом .
- – произошла ошибка соединения, например неправильное доменное имя. Событие не генерируется для HTTP-ошибок как, например, 404.
- – запрос успешно завершён.
- – запрос был отменён по причине истечения отведённого для него времени (происходит, только если был установлен таймаут).
- – срабатывает после , , или .
События , , и взаимно исключают друг друга – может произойти только одно из них.
Наиболее часто используют события завершения загрузки (), ошибки загрузки (), или мы можем использовать единый обработчик для всего и смотреть в свойствах объекта запроса детали произошедшего.
Также мы уже видели событие: . Исторически оно появилось одним из первых, даже раньше, чем была составлена спецификация. Сегодня нет необходимости использовать его, так как оно может быть заменено современными событиями, но на него можно часто наткнуться в старом коде.
Если же нам нужно следить именно за процессом отправки данных на сервер, тогда можно использовать те же события, но для объекта .