Navigator.sendBeacon()

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since April 2018.

Метод 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 в событии выгрузки страницы. Это решение приведёт к задержке отклика интерфейса браузера. Не используйте это.

js
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().

js
window.addEventListener("unload", logData, false);

function logData() {
  navigator.sendBeacon("/log", analyticsData);
}

Спецификации

Specification
Beacon
# sendbeacon-method

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

BCD tables only load in the browser

Смотрите также