Отслеживаем действия пользователя с помощью CSS

akok

Команда форума
Администратор
Ассоциация VN
Сообщения
24,598
Реакции
13,564
В этом посте вы сможете узнать, почему даже с выключенным JavaScript и без плагинов, вы все равно можете отсылать поведенческие данные на сторонний сервер.

Также здесь мы рассмотрим метод, как получить поведенческую информацию от пользователей используя только HTML и CSS.

Возможно, после прочтения поста, вам покажется что я "изобрел колесо". Так и есть, методы описанные в этом посте не новы, и используют спецификации которые поддерживают практически все браузеры.

Так или иначе, эта информация поможет вам понять один нестандартный метод отслеживания поведения пользователей, который на данный момент нельзя "отключить" (в настройках) или заблокировать (плагинами вроде AdBlock или Ghostery).

Предыстория
Представьте на минуту, что у вас есть:
  • Аудитория с выключенным JavaScript, или установлены плагины вроде Ghostery
  • Желание отслеживать поведение пользователей

Прежде чем пытаться найти решение для этой задачи, давайте рассмотрим какими методами отслеживания мы располагаем на данный момент:
  • JavaScript жучки, такие как Яндекс.Метрика, Google Analytics — действуют на стороне клиента.
  • Анализаторы логов приложения, такие как logstash, awstat — оперируют логами приложения на сервере.
  • Статичные счетчик — как правило, загружают скрытую картинку, или другой ресурс, не требуют выполнения JavaScript кода.

JavaScript жучки не подходят исходя из требований. За исключением таких, которые идут в комплекте с статичным счетчиком. К примеру, жучок для Яндекс.Метрики загружает изображение следующего вида:
HTML:
<noscript><div><img src="//mc.yandex.ru/watch/XXXXXXXX" style="position:absolute; left:-9999px;" alt="" /></div></noscript>

В случае, если у клиента не выполняется JavaScript, этот подход позволит получить такую информацию, как:
  • хиты
  • хосты
  • ip-адрес
  • время визита
  • … другие данные

Но есть одна проблема: вся информация носит статичный характер, то есть мы не получаем информацию о том, каким образом пользователь вел себя на странице.

Решение — используем CSS
В CSS мы можем загрузить внешний ресурс через инструкцию url(адрес-ресурса). Обычно этот ресурс загружается только тогда, когда он становиться необходим для рендеринга страницы. Почему бы не использовать эту особенность, для того чтобы собрать информацию о поведении пользователя? Мы вполне можем написать специальный CSS, который будет:
  • собирать данные о поведении пользователя
  • определять версии/особенности браузеров с помощью CSS-хаков
Итак, наша задача сводится к формированию HTML + CSS кода, который вынудит браузер, при взаимодействии с пользователем, сделать get запрос на наш сервер.
К примеру, мы желаем отслеживать клики по ссылкам. Для этого, мы можем использовать псевдокласс :active, а именно такой шаблон (jsfiddle):

HTML:
/* <a class="spycss" href="https://google.com">spycss</a>*/
.spycss:active::after {
    content: url("/backend/click-google");
}

При клике на такую ссылку, мы получим GET на /backend/click-google.
Похожим образом мы можем использовать и другие псевдоклассы:


HTML:
.spycss1:hover::after {
    content: url("/backend/hover");
}
.spycss2:focus::after {
    content: url("/backend/hover");
}
В обоих случаях мы принимаем GET на нашем сервере.


Ускоряемся вместе с SpyCss

Писать такой CSS вручную и отслеживать каждую ссылку — довольно проблемно и непродуктивно. Именно для этих целей я написал небольшую библиотеку SpyCss. С помощью нее можно генерировать отслеживающий HTML + CSS без особых проблем. К примеру, можно использовать такой код для генерации отслеживаемой ссылки:

PHP:
<?php
// Идентификатор пользователя, полезен для State-less бэкенда
$userId = 'get_from_cookie--OR--fetch_from_db';
// Адрес бэкенда, куда прийдут GET запросы.
$backendUrl = 'https://spy-css-backend/';
$s = new \SpyCss\SpyCss($userId, $backendUrl);
// Создаем ссылку формата
// <a class="scsssXXXX" href="https://hcbogdan.com">hcbogdan.com</a>
echo $s->builder()
    ->tag('a')
    ->content('hcbogdan.com')
    ->attribute('href', 'https://hcbogdan.com')
    ->interactions([
        new SpyCss\Interaction\Active('click_on_hcbogdan_com')
    ])
    ->get();
// Библиотека генерирует CSS с необходимыми инструкциями
echo '<style>'.$s->extractStyles().'</style>';

Теперь мы можем отслеживать клики по ссылкам и наведения мышки на DOM элементы. Давайте посмотрим на HTML5 формы. А именно на валидацию (jsfiddle):

PHP:
<form>
<input type="text" name="name" required />
</form>
<style>
.field:valid {
  background: red;
}
</style>

Получается точно таким же образом мы можем использовать псевдокласс :valid для отслеживания заполнения формы:

PHP:
// Создаем поле <input type="text"  class="scsssXXXX" required />
echo $s->builder()
->tag('input')
->attributes([
    'name' => 'you_name',
    'value' => '',
    'required' => true,
    'placeholder' => 'Напишите текст',
])
->interactions([
    new \SpyCss\Interaction\Valid('you_fill_input'),
])
->get();
echo '<style>'.$s->extractStyles().'</style>';

Когда пользователь заполнит поле — мы получим свой GET запрос.
Мы также можем отследить как долго пользователь держал курсор над DOM элементом (который получил состояние hover) с помощью css-анимаций. Например:

PHP:
@keyframes spycss {
  0% {background-image: url("/backend/0")}
  100% {background-image: url("/backend/100")}
}
.spycss:hover::after {
  animation: spycss 20s infinite;
}

Аналогичный пример с помощью библиотеки SpyCss (она добавит префиксы -webkit, -moz):
PHP:
echo $s->builder()
->tag('a')
->content('hcbogdan.com')
->attributes([
    'href' => 'https://hcbogdan.com',
    'target' => '_blank'
])
->interactions([
    new \SpyCss\Interaction\Online('view_on_hcbogdan_com'),
])
->get();
echo '<style>'.$s->extractStyles().'</style>';

Итоги
Даже с выключенным или недоступным JavaScript жучком, у нас есть с помощью CSS:
  • отслеживать поведение пользователей,
  • определять некоторые версии браузера
  • определять примерные размеры окна и PPI
  • определить ориентацию и тип устройства
В этом посте были рассмотрены некоторые, самые необходимые механизмы отслеживания. Полноценный пример, где используется все выше описанные подходы вы сможете найти тут.

habrahabr.ru
 
Назад
Сверху Снизу