Navigator.sendBeacon()

Метод navigator.sendBeacon() используется для асинхронной передачи небольшого количества информации поверх HTTP веб-серверу.

Синтаксис

navigator.sendBeacon(url [, data]);

Параметры

url
Параметр url устанавливает адрес, на который будут переданы данные параметра data.
data Необязательный
Параметр data может содержать объект типа ArrayBufferView (en-US), Blob, DOMString, или FormData, который будет передан.

Использует метод POST при передаче данных

Возвращаемые значения

sendBeacon() возвращает true, если браузер успешно поставил данные data в очередь отправления, в ином случае false.

Описание

Метод предназначен, главным образом, для передачи данных аналитики и диагностики на сервер, перед тем как страница будет закрыта. Так как отправление данных до закрытия страницы может привести к не достаточно полному сбору информации. Стандартный асинхронный XMLHttpRequest не подходит для этих целей, потому что большинство браузеров игнорируют его в событии unload (en-US).

Для решения этой проблемы ранее использовали синхронный XMLHttpRequest вызванный в событии unload или beforeunload (en-US) с данными для передачи. Синхронный XMLHttpRequest блокирует процесс выгрузки документа и текущая страница закрывается не сразу. Ситуация усугубляется, если пользователь уходит с вашей страницы по ссылке или нажимает кнопку "назад". Новая страница не будет загружена в этой вкладке, пока не выгрузится старая. В глазах пользователя, новая страница выглядит заторможенной, хотя на самом деле, это связанно с текущей, выгружаемой, страницей.

Существуют и другие способы обойти эту проблему. Один из них - создание элемента <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
Beacon
Определение 'sendBeacon()' в этой спецификации.
Кандидат в рекомендации Изначальная спецификация

Совместимость с браузерами

BCD tables only load in the browser

See also