Если вы хотите обеспечить сбор некоторой информации о пользователе до того, как он покинет определенный раздел вашего сайта или веб-приложения, вы можете использовать веб-API Beacon и PageVisivibility, чтобы гарантировать успешную отправку данных в вашу собственную внутреннюю службу.

Проблема с отправкой запросов HTTP-запросы

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

С этим есть несколько проблем:

  • Браузер не будет ждать завершения запроса, поэтому его можно отменить.
  • Использование метода ожидания завершения запроса, т.е. синхронно, может повлиять на время загрузки следующей страницы (если применимо)
  • Некоторые браузеры будут игнорировать запросы, сделанные в обработчике unload, а другие вообще не будут запускать событие unload (подробнее об этом позже)

Вот почему использование Beacon API - лучший выбор, если вы хотите, чтобы последний запрос к вашей серверной службе был выполнен, даже если пользователь полностью закрывает свой браузер.

Чем отличается Beacon API?

Используя Beacon API, эти последние запросы, отправленные страницей, гарантированно будут отправлены. Они также отправляются асинхронно, поэтому при следующей загрузке страницы не возникает побочных эффектов.

По этим причинам нет необходимости писать какой-либо дополнительный код, чтобы гарантировать, что эти окончательные запросы будут отправлены в вашу внутреннюю службу и, следовательно, могут упростить ваш код.

Короче говоря, Beacon API будет

  • Надежно убедитесь, что данные, переданные в функцию sendBeacon, отправляются по указанному URL-адресу.
  • Отправляйте запросы асинхронно, чтобы не повлиять на время загрузки последующих страниц.

Использование Beacon API

Так как же работает Beacon API?

Что ж, это так же просто, как вызвать одну функцию для объекта window.navigator. Мы могли бы переписать предыдущий пример, чтобы вместо него использовать Beacon API.

Хотя браузерная поддержка довольно хороша, вы можете захотеть проверить, существует ли функция sendBeacon для объекта navigator, прежде чем пытаться ее вызвать.

Функция sendBeacon отправит запрос POST на URL-адрес, указанный в качестве первого аргумента. Второй аргумент - это данные, которые нужно отправить.

Формат данных может быть anArrayBuffer, ArrayBufferView, Blob, DOMString, FormData или URLSearchParams.

Не используйте событие разгрузки

Я упоминал ранее, что некоторые браузеры не запускают событие unload, когда вкладка закрывается или пользователь переходит на другую страницу. Особенно это касается мобильных браузеров.

С этой страницы сайта Google Developers:

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

Итак, как лучше всего отправлять запросы Beacon после завершения сеанса страницы? Что ж, мы можем использовать API PageVisibility, чтобы определить, ушел ли пользователь с текущей вкладки.

Использование PageVisibility API

Как следует из названия, PageVisibility API можно использовать для определения того, отображается ли документ на экране пользователя, т. Е. Ваша вкладка находится в фокусе.

Вы можете получить доступ к текущему состоянию из document.visibilityState, который вернет одно из значений prerender, hidden или, скорее всего, если вы запускаете его в своих инструментах разработчика visible. Вы можете использовать это свойство для проверки в любой конкретной точке вашего кода, видима ли в данный момент вкладка для пользователя.

В нашей ситуации это не так полезно, но есть событие, которое вы можете прослушать, чтобы узнать об изменениях в visibilityState. Таким образом, вы можете отправить запрос маяка, когда это изменится.

Итак, теперь, когда пользователь уходит со страницы, срабатывает событие visibilityChange, и мы можем безопасно отправлять наши аналитические данные или информацию журналов в нашу внутреннюю службу.

Полный пример

Давайте рассмотрим полный пример, который вы можете запустить локально и поэкспериментировать.

Сначала настройте проект с зависимостями для Express:

mkdir beacon-example
cd beacon-example
npm init -y
npm install express body-parser
mkdir public
touch public/index.html
touch app.js

Затем в файле app.js настройте сервер Express для приема наших запросов Beacon.

Установите сервер Express, работающий с:

node app.js

Затем внутри index.htmlfile, содержащегося в папке public, мы можем добавить код JavaScript для отправки запросов Beacon.

Хотя это немного грубо, но, надеюсь, вы сможете понять, как потенциально можно собирать информацию о том, как пользователи взаимодействуют с вашей страницей или веб-приложением, и передавать ее обратно в серверную службу с помощью sendBeacon запроса.

Вы можете расширить этот пример, добавив в массив events информацию о дополнительных событиях. Например, когда пользователь щелкает в любом месте страницы:

Если вы перейдете к терминалу, на котором запущена серверная служба Express, вы увидите результат, который выглядит примерно так:

Received Beacon:  [
  { type: 'Session Start', time: 1603812976748 },
  { type: 'Click', x: 122, y: 151 },
  { type: 'Session End', time: 1603812979156 }
]

Вывод

В этом руководстве мы рассмотрели проблему с отправкой аналитики и информации журнала в серверную службу с помощью простого HTTP-вызова, а также то, почему событие unload не следует использовать для прослушивания окончания сеанса.

Теперь мы знаем, что Beacon API обеспечивает безопасный и надежный способ передачи данных такого типа обратно в наши собственные серверные службы, не влияя на время загрузки последующих страниц.

Кроме того, мы видели, как PageVisibility API предоставляет безопасное событие, которое может сообщить нам, когда пользователь уходит со страницы, даже на мобильных устройствах.

Спасибо за чтение. Если вы нашли это полезным, подпишитесь на меня в Twitter (@codebubb), чтобы увидеть больше руководств.