Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Что именно делает код Яндекс метрики? (https://javascript.ru/forum/events/49529-chto-imenno-delaet-kod-yandeks-metriki.html)

GDR 17.08.2014 02:21

Что именно делает код Яндекс метрики?
 
Доброго времени суток всем!
Будучи любознательным от природы пытаюсь сейчас освоить JavaScript в различных, прикладных областях применения.

В частности, заинтересовался, как именно работает код Яндекс-метрики, который устанавливается на страницы сайтов для подсчета количества посетителей и другой статистики.

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

Ниже код счетчика яндекс метрики созданный под выдуманный аккаунт с id=12345678. Если не возражаете, я попробую самостоятельно изложить то, что я на данный момент могу сказать о его работе, приводя фрагменты кода и описывая их работу. в ходе рассуждения буду отмечать возникающие вопросы при помощи фразы "_НЕ_ПОНЯТНО_".

Начну с самого легкого - с раздела <noscript> в конце кода, а именно:
<noscript><div><img src="//mc.yandex.ru/watch/12345678" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
как я понимаю, этот кусок кода срабатывает, если в браузере заблокирован обработчик JS и, в этом случае, просто происходит вызов именной страницы счетчика на сайте яндекса по адресу //mc.yandex.ru/watch/12345678 что, по-видимому, вызывает инкремент счетчика на стороне сервера яндекса.

Далее, по структуре я могу сказать, что оставшийся код в рамках <script> </script> представляет из себя описание и вызов на месте функции (function (d, w, c) { ...}) которой в качестве параметров передаются глобальные document, window и параметр "yandex_metrika_callbacks" представляющий из себя свойство объекта window (или w внутри самой функции) для доступа в формате w[c].
_НЕ_ПОНЯТНО_, что делает вот этот кусок строки: " w[c] = w[c] || [] "?

Теперь вот это:
(w[c] = w[c] || []).push(function() {
try {
w.yaCounter12345678 = new Ya.Metrika({id:12345678,
clickmap:true,
trackLinks:true,
accurateTrackBounce:true});
} catch(e) { }
});

Про приведенный выше кусок кода могу сказать следующее:
в конец массива объектов w.yandex_metrika_callbacks при помощи функции push добавляется новый объект w.yaCounter12345678 cо значениями свойст передаваемыми при создании объекта типа Ya.Metrika при помощи оператора new. При этом используется конструкция try {...} catch(e) для отлова ошибки. Верно?
_НЕ ПОНЯТНО_, для чего создается этот новый объект? Как сервер яндекса получает к нему доступ? И что происходит с этим объектом далее?

Идем далее:
var n = d.getElementsByTagName("script")[0],
s = d.createElement("script"),
f = function () { n.parentNode.insertBefore(s, n); };
s.type = "text/javascript";
s.async = true;
s.src = (d.location.protocol == "https:" ? "https:" : "http:") + "//mc.yandex.ru/metrika/watch.js";

if (w.opera == "[object Opera]") {
d.addEventListener("DOMContentLoaded", f, false);
} else { f(); }

Тут вроде более-менее ясночто происходит: в html коде страницы ищется первый элемент с тегом script и присваевается в переменную n. Затем создается новый элемент того же типа в переменной s, у которого среди прочих аттрибутов (после некоторых пассов) задается источник с адресом "http://mc.yandex/metrik/watch.js". Далее идет проверка на "оперность" ,браузера и при ее отсутствии запускается функция f, которая просто вставляет тег s в начала всего блока тегов типа script.
_НЕ_ПОНЯТНО_, почему нельзя было сразу в html код включить код с вызовом адреса http://mc.yandex.ru/metrika/watch.js? Для чего все эти усилия по поиску массива тегов типа script и вставке туда этого адреса?
Неужели это для того, чтобы выяснить какой используется протокол (http или https)? Ведь, в итоге все равно в "живом" html коде странице банально появляется вызов JS-скрипта со страницы яндекса (.../watch.js), который наверное и осуществляет увеличение счетчика?

Вот такие мысли роятся в голове любознательного ламера:help: .
Если лень будет комментировать мои наивные вопросы, просьба просто дать свое видение работы кода счетчика приведенного для удобства полностью ниже.

с уважением, Дмитрий



<!-- Yandex.Metrika counter -->
<script type="text/javascript">
(function (d, w, c) {
(w[c] = w[c] || []).push(function() {
try {
w.yaCounter12345678 = new Ya.Metrika({id:12345678,
clickmap:true,
trackLinks:true,
accurateTrackBounce:true});
} catch(e) { }
});

var n = d.getElementsByTagName("script")[0],
s = d.createElement("script"),
f = function () { n.parentNode.insertBefore(s, n); };
s.type = "text/javascript";
s.async = true;
s.src = (d.location.protocol == "https:" ? "https:" : "http:") + "//mc.yandex.ru/metrika/watch.js";

if (w.opera == "[object Opera]") {
d.addEventListener("DOMContentLoaded", f, false);
} else { f(); }
})(document, window, "yandex_metrika_callbacks");
</script>
<noscript><div><img src="//mc.yandex.ru/watch/12345678" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->

GDR 17.08.2014 05:03

Цитата:

Сообщение от Rise (Сообщение 326234)
GDR, кури watch.js :D

а к чему тогда все эти танцы с установкой кода который только что и делает что ставит на страницу линк на watch.js?

GDR 17.08.2014 05:22

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

<!-- Yandex.Metrika counter -->
<script src="//mc.yandex.ru/metrika/watch.js" type="text/javascript"></script>
<div style="display:none;"><script type="text/javascript">
try {
var yaCounterXXXXXX = new Ya.Metrika({id: XXXXXX, enableAll: true});
var yaCounterYYYYYY = new Ya.Metrika({id: YYYYYY, enableAll: true});
//...
}
catch(e) { }
</script></div>
<noscript><div><img src="//mc.yandex.ru/watch/XXXXXX" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<noscript><div><img src="//mc.yandex.ru/watch/YYYYYY" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
<!-- /Yandex.Metrika counter -->

GDR 17.08.2014 05:26

Цитата:

Сообщение от Rise (Сообщение 326238)
GDR, вот там и написано, разбирайся, если так интересно.

Боюсь, я в коде watch.js на текущем этапе разобраться не смогу - там около 10 экранов кода сплошным текстом без отступов.

Мне хотя бы понять логику вызова счетчика...

MallSerg 17.08.2014 05:31


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

GDR 17.08.2014 05:42

Цитата:

Сообщение от MallSerg (Сообщение 326242)

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

спасибо за дельный ответ! не подскажете, в каком месте кода происходит это навешивание и каким боком тут объект типа Ya.Metrika?

MallSerg 17.08.2014 05:51

Цитата:

Сообщение от GDR
в каком месте кода происходит это навешивание


GDR 17.08.2014 15:22

я, видимо, не совсем правильно поставил вопрос: я хотел понять что делает установщик кода метрики, а не сам код метрики...

Kolyaj 18.08.2014 14:58

Установщик кода метрики подключает на страницу код метрики и создаёт экземпляр класса Ya.Metrika, передавая ему параметры, с которыми нужно собирать статистику.

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

GDR 18.08.2014 23:37

Цитата:

Сообщение от Kolyaj (Сообщение 326407)
Установщик кода метрики подключает на страницу код метрики и создаёт экземпляр класса Ya.Metrika, передавая ему параметры, с которыми нужно собирать статистику.

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

Большое спасибо. У меня были смутные догадки относительно этих тацев с бубнами вокруг вызова watch.js... Получается, что сначала грузится страница с основным кодом html, далее задаются параметры объекта метрики (это все происходит достаточно быстро), а затем javascript модифицирует код страницы так, чтобы вызвать watch.js уже после загрузки страницы, так как watch.js, по-видимому, вносит весомый "вклад" в замедление скорости загрузки. у меня просто выпало из внимания, что после изменения кода страницы браузер, видимо, заново прогоняет "через себя" код страницы, что и вызывает вызов внешнего скрипта. Теперь все стало ясно. Еще раз благодарю!
с уважением, Дмитрий


Часовой пояс GMT +3, время: 16:53.