Как стать автором
Обновить

Сниффинг истории браузера с помощью favicon

Время на прочтение2 мин
Количество просмотров29K
Метод позволяет определить посещаемые пользователем сайты с помощью запроса иконок сайта со страницы. Идея этого метода пришла мне в голову при обсуждении с другом возможностей аналитики поведения пользователей на его сайте. Мы обсуждали, какие метрики нужно и какие не нужно собирать о его посетителях. Я подумал, что было бы неплохо узнать, какими еще сайтами пользуются его посетителями. В голову тут же пришел старый, но известный способ с CSS-стилями.

Тот способ основывается на использовании метода DOM элемента getComputedStyle. Будучи вызванным у HTMLAnchorElement, он позволяет различать :visited и обычные состояния ссылок на популярные сайты.

Баг давно закрыли и больше им воспользоваться нельзя.

Мой метод основывается на том факте, что favicon.ico посещаемых пользователем сайтов, скорее всего, будут находиться у него в кэше и, соответственно, загрузятся быстрее, чем тех сайтов, на которых он ни разу не был. Браузеры очень агрессивно кэшируют favicon.ico, что лишь увеличивает надежность такого способа.

Ниже приведен полный исходный код proof-of-concept реализации этого способа. С его помощью можно продемонстрировать, что вы посещаете сайт habrahabr.ru, но ни разу не были на сайте hornet.com.

var diffTreshold = 200; // Порог времени, который необходимо преодолеть, чтобы считать, что пользователь посетил сайт.
var body = document.querySelector('body');

var testResults = [];
var testCases = [
  'hornet.com', 'habrahabr.ru'
];

testCases.forEach(test);

function test (host) {
  var start = new Date();
  var img = new Image();
  img.src = 'http://'+host+'/favicon.ico';
  img.onload = function () {
    saveResult(host, start, new Date());
  }
  body.appendChild(img);
}

function saveResult (host, start, end) {
  var diff = end - start;
  testResults.push({
    host: host,
    start: start,
    end: end,
    diff: diff,
    visited: diff <= diffTreshold
  });
}



Этот код дает не очень точные результаты, потому что использует константу diffTreshold, которая подбирается эмпирически. Эта переменная — количество миллисекунд, прошедших с начала загрузки картинки до ее окончания, которое следует считать попаданием в кэш браузера.

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

Этот способ имеет также и один нерешенный мной недостаток: после первого такого теста его последующие запуски сделают результаты бесполезными.

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

UPD:
Удивило, чтот пост стал достоин инвайта. Видимо, это действительно очень интересная тема. Попробую реализовать этот метод в виде готовой библиотеки.
Теги:
Хабы:
Всего голосов 59: ↑54 и ↓5+49
Комментарии20

Публикации

Истории

Работа

Ближайшие события

2 – 18 декабря
Yandex DataLens Festival 2024
МоскваОнлайн
11 – 13 декабря
Международная конференция по AI/ML «AI Journey»
МоскваОнлайн
25 – 26 апреля
IT-конференция Merge Tatarstan 2025
Казань