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
в событии выгрузки страницы. Это решение приведёт к задержке отклика интерфейса браузера. Не используйте это.
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 |
---|
Beacon # sendbeacon-method |
Совместимость с браузерами
BCD tables only load in the browser
Смотрите также
navigator
WorkerNavigator.sendBeacon()
(ИспользованиеsendBeacon()
в workers)