Не cookie единым…

07.04.2024

Заголовок – мутный, согласен. И чтобы вы сразу не разбежались, кратко изложу то, о чем я хочу рассказать. Помимо cookie в браузере пользователя, есть еще несколько мест, где бы мы могли хранить информацию о его поведении. Вот об этих местах, чем они лучше или хуже cookie, как эти знания можно применить на практике, а также о том, что нас может сдерживать мы и поговорим.

Иными словами, эта статья об альтернативных способах хранения информации, о поведении пользователя и прикладных методах ее использования.

Читайте внимательно, будет интересно, а если появятся вопросы, вы мне их в комментариях задайте и я обязательно отпишусь.

Window

Сначала о наших возможностях. Одним из фундаментальных понятий JavaScript является область видимости (scope). Область видимости – это контекст выполнения кода, в котором значения и выражения могут быть видимы и мы можем на них ссылаться. Если представить образно, то это некая коробка за пределы которой доступ нам запрещен. JavaScript имеет четыре типа области видимости:

  • Глобальная область видимости – это самый верхний уровень, все что там происходит доступно всем объектам нашего сайта;
  • Область видимости модуля;
  • Область видимости функции;
  • Область видимости блока (для GTM эта область видимости не актуальна вследствие того, что в нем используется не самая новая версия JavaScript).

Так вот, все наши возможности ограничены глобальной областью видимости или, иначе говоря, окном браузера (объект window), то есть при всем желании в файловую систему пользователя мы залезть не сможем (не должны смочь)  и следовательно все, что мы имеем расположено в этом окне. Сейчас продемонстрирую, как это выглядит. Переходим в консоль браузера, как это сделать и о других возможностях инструментов веб-разработчика Google Chrome можно прочитать здесь.

На скриншоте открыта вкладка Console, по очереди набираем:

  1. window –  глобальный объект, который дает доступ к браузерному API;
  2. window.document – является частью глобального объекта window, ссылается на страницу сайта, служит точкой входа для получения кода страницы, его можно было бы вызвать и просто набрав document без window;
  3. строка cookie в виде пар ключ/значение, записанных через точку с запятой;
  4. определяем глобальную переменную “a” присваиваем ей число 12, (var – ключевое слово JavaScript для определения переменных);
  5. вызываем ее, явно указав, что она лежит в глобальной области видимости;
  6. вызываем переменную  “a”  без window, эта запись и запись под номер 5  идентичны.

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

Cookie

Теперь поговорим про cookie, что это и какие ограничения есть у них. Если кратко cookie – это строковые данные устанавливаемые сервером в браузер, имеющие формат ключ/значение, являющиеся частью HTTP протокола. При повторном запросе браузер отправляет их обратно на сервер, таким образом, давая понять серверу откуда пришел запрос. К этому моменту мы должны начать понимать, что cookie – это способ общения на уровне клиент – сервер и в общем-то не маркетинговый инструмент.  Кроме того, cookie имеют определенные ограничения:

– пара – ключ/значение не должна занимать более 4Кб;

– количество cookie на один домен ограничивается 20+ на сайт;

– сторонние cookie могут быть запрещены браузером (Safari делает это по умолчанию);

– установка отслеживающих cookie пользователям из стран ЕС требует их явного согласия на это в соответствии с законодательством (GDPR);

– если сервер отправит cookie со значением HTTPOnly, они будут блокированы для JavaScript.

И это еще не все. Давайте вспомним, какие сложности нам пришлось преодолеть, чтобы извлечь данные из строки и привести их в удобочитаемый вид. Не кажется ли вам, что разработчики самого популярного языка для Web могли бы придумать более удобные и эффективные методы хранения и работы с данными для браузерного JavaScript?

LocalStorage, sessionStorage

Объекты window.localStorage и window.sessionStorage – это два способа хранения данных в браузере. Они почти одинаковы, но есть одно отличие: данные в localStorage сохраняются навсегда, а в sessionStorage – только до закрытия вкладки. Пока вкладка открыта, данные в sessionStorage остаются доступными, даже если перезагрузить страницу. Но если открыть страницу в новой вкладке или окне, это будет уже новая сессия со своими данными. Ну и поскольку эти методы почти идентичны, все манипуляции с методом localStorage показанные ниже, будут в равной степени относиться и к объекту sessionStorage.

Основные характеристики объектов:

  • хранятся в виде строковых пар ключ/значение;
  • не отправляют данные на сервер при каждом запросе, тем самым снижая нагрузку на сервер и браузер;
  • можно хранить более 5 мегабайт* данных (параметр меняется в настройках);
  • сервер не может взаимодействовать с объектами Web Storage через HTTP-заголовки, только через JavaScript
  • имеют удобный JavaScript-интерфейс.

*5 мегабайт  – много это или мало? Для сравнения – объем текстовых данных романа Л.Н. Толстого “Война и мир” (огромная книжка) – составляет 6,14 мегабайт (информация взята отсюда), нам столько информации в браузер пользователя за всю жизнь не записать.

Основные отличия объектов:

  • localStorage
    • данные сохраняются “навсегда” и не удаляются по прошествии определенного времени, даже после перезапуска браузера или операционной системы;
    • один на все вкладки и окна в рамках источника (домен/протокол/порт), при этом URL-путь может быть разным, нет доступа для других доменов, протоколов, портов;
  • sessionStorage
    • сохраняет данные после обновления/перезагрузки страницы, но не после закрытия/открытия вкладки;
    • существует только в рамках текущей вкладки браузера;
    • другая вкладка с той же страницей будет иметь другое хранилище;
    • привязан не только к источнику, но и к вкладке браузера.

Методы объектов LocalStorage, sessionStorage

  • setItem(key, value) – сохранить пару ключ/значение;
  • getItem(key) – получить данные по ключу key;
  • removeItem(key) – удалить данные с ключом key;
  • clear() – удалить всё;
  • key(index) – получить ключ на заданной позиции;
  • length – количество элементов в хранилище.

Синтаксис:

События объектов LocalStorage, sessionStorage

Во время обновления данных, генерируется событие storage:

  • key – ключ, который обновился (null, если вызван .clear());
  • oldValue – старое значение (null, если ключ добавлен впервые);
  • newValue – новое значение (null, если ключ был удален);
  • url – url документа, где произошло обновление;
  • storageArea – объект localStorage или sessionStorage, где произошло обновление.

Синтаксис:

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

С теорией покончено. Не беспокойтесь если в данный момент вам что-то не понятно, сейчас перейдем к примерам и все встанет на свои места.

Примеры кода

Открываем инструменты разработчика, вкладка Application:

Вот наши хранилища, пока они пусты. Переключаемся на вкладку Console:

Я отправил в localStorage данные, ключ – ‘имя’, значение – ‘Александр’ и тут же получили установленные данные. А вот они и в нашем хранилище:

Теперь давайте удалим данные:

Я применил метод removeItem для того, чтобы удалить конкретное значение и тут же проверил, метод getItem вернул нам null, это значит что по данному ключу уже ничего нет. Если нам нужно будет очистить хранилище полностью мы воспользуемся методом localStorage.clear() – ему не надо передавать никакие параметры, он все сделает сам.

Значением может быть не только простая строка, но и более сложная структура данных, преобразованная в строку, давайте вернемся в консоль:

Мы создали объект data (он может быть сколь угодно сложным), преобразовали его в строку с помощью метода JSON.stringify() (помним, что в localStorage мы можем хранить только строки), сохранили, проверили результат. Затем c помощью метода JSON.parse() преобразовали хранящийся в браузере строку обратно в объект JS с которым можно работать стандартными методами. 

А вот, что теперь у нас лежит в localStorage (вкладка Application):

После эквилибристики с методами Web Storage, думаю, много стало понятней. Переходим в Google Tag Manager, попробуем что-нибудь сделать и там.

Как использовать localStorage в Google Tag Manager

Прежде всего создадим константу и присвоим ей название нашего объекта, в нем мы будем хранить пользовательские данные. Я назову его ‘my_data’, но можно записать доменное имя сайта получив его из URL.

Затем создаем пользовательский HTML тег с триггером Initialization – All Pages:

Еще скриншот:

Номера ниже соответствуют номеру строки кода на скриншоте.

  1. Создаем функцию increaseLocalStorageValue, которая в качестве единственного параметра принимает название ключа;
  2. Создаем объект init с двумя полями и нулевыми значениями;;
  3. Создаем функцию getLocalStorageDate, которая на вход принимает название объект из localStorage и возвращает объект JavaScript;
  4. Создаем функцию setLocalStorageDate, которая принимает в качестве параметров название объекта и сам объект и устанавливает его в браузер;
  5. Создаем функцию isLocalStorageDate, которая принимает название объекта и возвращает true, если объект существует или false, если его нет;
  6. Получаем в переменную data обработанные данные, если они уже существуют в браузере или объект init;
  7. Обновляем данные в хранилище.

Кода получилось довольно много, но он достаточно простой. Осталось создать два тега, которые будут при возникновении событий вызывать функцию increaseLocalStorageValue и перезаписывать данные в localStorage.

И еще тег:

Здесь комментировать нечего. Вызываем функцию и передаем ей название поля. Для поля page_view – триггер All Page, для phone_click – клик по ссылке с номером телефона.

Возвращаемся на сайт, открываем вкладку Application Dev Tools.  Инициируем события. С каждым переходом по сайту и кликом по номеру телефона данные должны обновляться. Перед тестированием не забудьте опубликовать контейнер.

Думаю, это все. Какие данные о поведении пользователя вы будете собирать и что с ними впоследствии делать ,зависит только вас – возможности безграничны.

Заключение

Хочется верить, что написанное мной поможет вам в решении ваших практических задач или наведет на какие-либо мысли. Помните – современный маркетинг начинается на стороне сервера. Учите JavaScript и никогда не сдавайтесь. Удачи!

Ссылки

Категории:
Веб-аналитика
Павел Корякин
Павел Корякин

Веб-аналитик, маркетолог, веб-разработчик — t.me/pavel_koryakin

Все комментарии

  • Есть вопрос – согласно правил GDRP, если клиент отказал в отслеживании, то мы не имеем права записывать какую-либо информацию ему в куки. Но вопрос – если сохранять информацию в localstorage, будет ли это нарушением правил GDRP?

    Дмитрий 08.04.2024 17:20 Ответить
    • Я не большой специалист по GDRP, но думаю, если мы используем обезличенные данные и намеренно не передаем их третьим лицам, то никаких проблемы с использованием браузерных хранилищ у нас не должно быть. Если же вопрос в том безопасно ли там хранить конфиденциальную информацию – мой ответ нет небезопасно.

      Павел Корякин Павел Корякин 10.04.2024 21:23 Ответить
  • При каких сценариях это можно применить? Есть примеры из практики?

    Наиль 09.04.2024 17:05 Ответить
    • Первое, что приходит в голову – это персонификация выдачи при наступлении того или иного события. Хранить информацию в браузере о том сколько раз пользователь посетил наш сайт или совершил то или иное действие, думаю, вполне безопасно и не является нарушением каких-либо норм. Покажите всплывающее окно со скидкой или наоборот закройте для пользователя тот или иной ресурс.

      Павел Корякин Павел Корякин 10.04.2024 21:32 Ответить

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *