Navigator.sendBeacon()

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

Синтаксис

navigator.sendBeacon(url [, data]);

Параметры

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

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

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

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

Описание

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

Для решения этой проблемы ранее использовали синхронный XMLHttpRequest вызванный в событии unload или beforeunload с данными для передачи. Синхронный 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