Если вы хотите обеспечить сбор некоторой информации о пользователе до того, как он покинет определенный раздел вашего сайта или веб-приложения, вы можете использовать веб-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.html
file, содержащегося в папке 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), чтобы увидеть больше руководств.