--- title: Navigator.sendBeacon() slug: Web/API/Navigator/sendBeacon tags: - API - Beacon - sendBeacon - Маяк - Производительность - метод - сеть translation_of: Web/API/Navigator/sendBeacon ---
Метод navigator.sendBeacon()
используется для асинхронной передачи небольшого количества информации поверх {{Glossary("HTTP")}} веб-серверу.
navigator.sendBeacon(url [, data]);
url
url
устанавливает адрес, на который будут переданы данные параметра data
.data
{{optional_inline}}data
может содержать объект типа {{domxref("ArrayBufferView")}}, {{domxref("Blob")}}, {{domxref("DOMString")}}, или {{domxref("FormData")}}, который будет передан.Использует метод POST при передаче данных
sendBeacon()
возвращает true
, если браузер успешно поставил данные data
в очередь отправления, в ином случае false
.
Метод предназначен, главным образом, для передачи данных аналитики и диагностики на сервер, перед тем как страница будет закрыта. Так как отправление данных до закрытия страницы может привести к не достаточно полному сбору информации. Стандартный асинхронный {{domxref("XMLHttpRequest")}} не подходит для этих целей, потому что большинство браузеров игнорируют его в событии {{event("unload")}}.
Для решения этой проблемы ранее использовали синхронный XMLHttpRequest
вызванный в событии unload
или {{event("beforeunload")}} с данными для передачи. Синхронный XMLHttpRequest
блокирует процесс выгрузки документа и текущая страница закрывается не сразу. Ситуация усугубляется, если пользователь уходит с вашей страницы по ссылке или нажимает кнопку "назад". Новая страница не будет загружена в этой вкладке, пока не выгрузится старая. В глазах пользователя, новая страница выглядит заторможенной, хотя на самом деле, это связанно с текущей, выгружаемой, страницей.
Существуют и другие способы обойти эту проблему. Один из них - создание элемента {{HTMLElement("img")}} и установка атрибута src
в событии выгрузки. Это может сработать, потому что большинство браузеров остановят основной процесс, а вместе с ним и выгрузку страницы, до загрузки изображения. Ещё один способ - создать пустой цикл на несколько секунд, таким образом придержав основной поток и дав асинхронному XMLHttpRequest
выполниться.
Но, проблема в том, что все эти методы не надёжны и приводят к значительным задержкам отклика интерфейса браузера. Не говоря о том, что всё это - плохой стиль написания кода.
В примере ниже показан код отправления аналитики при помощи синхронного XMLHttpRequest
в событии выгрузки страницы. Это решение приведёт к задержке отклика интерфейса браузера. Не используйте это.
window.addEventListener("unload", logData, false); function logData() { var client = new XMLHttpRequest(); client.open("POST", "/log", false); // последний параметр устанавливает синхронный стиль client.setRequestHeader("Content-Type", "text/plain;charset=UTF-8"); client.send(analyticsData); }
Здесь-то и найдётся применение sendBeacon()
. При использовании метода sendBeacon()
, данные будут переданы на сервер асинхронно, как только браузер найдёт оптимальный момент для этого. Это не вызовет задержек выгрузки и не повлияет на время загрузки следующей страницы. Решает все проблемы при отправлении аналитики: данные надёжно доставляются, это происходит асинхронно, не влияет на время выгрузки и загрузки страниц. Кроме того, код выглядит проще, чем при использовании прочих ухищрений.
Следующий пример покажет, как сделать отправление аналитики красиво и просто с помощью sendBeacon()
.
window.addEventListener("unload", logData, false); function logData() { navigator.sendBeacon("/log", analyticsData); }
Specification | Status | Comment |
---|---|---|
{{SpecName('Beacon', '#sec-sendBeacon-method', 'sendBeacon()')}} | {{Spec2('Beacon')}} | Изначальная спецификация |
{{Compat("api.Navigator.sendBeacon")}}
sendBeacon()
в workers)