К содержанию
ActionPulse

Несовпадение версий и контрольных сумм

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

Кому
Тем, кто раздаёт файлы трекера со своего домена
Проверено
На этой странице

Все проблемы этой группы имеют одну природу: байты, которые исполняет браузер, не те, которые ожидает кто-то из участников — тег, ядро трекера или манифест. Диагностика поэтому всегда сводится к сравнению сумм, а не к перезапуску.

Три источника правды

Источник Что в нём Где смотреть
Манифест версии размер, SHA-256, SHA-384 и готовое значение integrity каждого файла https://YOUR_ACTIONPULSE_HOST/v1/sdk/browser/0.6.0/manifest.json
Заголовки ответа ETag — это SHA-256 отданного файла в шестнадцатеричном виде ответ на запрос файла
Тег на странице значение integrity, которое браузер обязан подтвердить разметка страницы

Манифест отдаётся без авторизации, поэтому его удобно читать из скрипта развёртывания:

curl --fail --silent --show-error https://YOUR_ACTIONPULSE_HOST/v1/sdk/browser/0.6.0/manifest.json | python3 -m json.tool

В нём четыре записи — core, replay, diagnostics, picker — для файлов tracker.js, replay.js, diagnostics.js, picker.js версии 0.6.0. Поле sha384 — шестнадцатеричная сумма, поле integrity — та же сумма в другом представлении, именно её ждёт браузер. Одно значение из другого «на глаз» не выводится, поэтому не пытайтесь подставить sha384 в тег.

Решение проблем

Контрольная сумма не совпала и браузер отказался выполнять файл

Вероятная причина. Значение integrity в теге не соответствует байтам файла. Пять типовых источников: значение взято из другой установки или другой версии; в теге остался плейсхолдер SRI_FROM_MANIFEST; версию в адресе обновили, а integrity — нет; раздача изменила байты (минификация, перепаковка, подстановка переменных, изменение переводов строк при копировании); нет crossorigin="anonymous" при загрузке файла с другого домена, из-за чего браузер не может проверить сумму вовсе.

Как проверить. В консоли будет сообщение о том, что ресурс не прошёл проверку integrity, и файл не выполнится. Дальше сравните три значения:

# 1. Что ждёт браузер: значение integrity из тега на странице.
# 2. Что объявляет манифест:
curl --fail --silent https://YOUR_ACTIONPULSE_HOST/v1/sdk/browser/0.6.0/manifest.json \
  | python3 -c "import json,sys; print(json.load(sys.stdin)['assets']['core']['integrity'])"

# 3. Что получается из файла, который реально раздаётся:
printf 'sha384-%s\n' "$(openssl dgst -sha384 -binary tracker.js | openssl base64 -A)"

Все три строки должны совпадать посимвольно. Если расходятся первая и вторая — неверное значение в теге. Если расходятся вторая и третья — файл изменён при раздаче.

Безопасное исправление. Возьмите значение assets.core.integrity из манифеста своей установки и подставьте его в тег вместе с адресом той же версии — одной правкой. Готовый сниппет с корректной суммой есть в кабинете, на экране установки. Правка тега обратима и данных не касается.

Если не помогло. Проверьте, не преобразует ли файл ваш CDN или прокси: включённые «оптимизация JavaScript», автоматическая минификация и подстановка переменных ломают проверку целостности. Отдавайте байты без изменений. Если integrity временно мешает разбираться, уберите атрибут на одну проверку — но не оставляйте так на постоянной основе: без него подмена файла в раздаче перестаёт быть заметной.

Загружается старая версия из кэша

Вероятная причина. Зависит от того, какой адрес указан в теге. Версионный адрес неизменяем и кэшируется на год — по нему принципиально не может прийти другая версия, потому что содержимое по этому адресу не меняется. Совместимый короткий адрес /v1/t.js версией не привязан: он кэшируется на час и до суток может отдаваться из кэша, пока обновление подтягивается в фоне. Значит, «старая версия» — это либо совместимый адрес, либо кэш вашей собственной раздачи, либо сервис-воркер сайта.

Как проверить. Версия загруженного трекера видна с двух сторон:

pp.trackerVersion;  // версия, которая реально исполняется на странице

и в сетевой панели — в заголовке X-PP-Tracker у запросов на /v1/track. Сравните с ожидаемой. Заодно посмотрите заголовки ответа на сам файл:

curl --silent --head https://YOUR_ACTIONPULSE_HOST/v1/sdk/browser/0.6.0/tracker.js | grep -i -E '^(etag|cache-control)'

У версионного файла кэширование годовое и есть ETag; у совместимого адреса ETag нет, а срок кэша — час.

Безопасное исправление. Перейдите на версионный адрес с проверкой целостности — тогда версия задаётся тегом, а не поведением кэша. Это рекомендуемый вариант для рабочей среды. Для однократной проверки достаточно жёсткого обновления страницы с отключённым кэшем в инструментах разработчика: данных это не касается.

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

Версия ядра и версия дополнительных модулей разошлись

Вероятная причина. Ядро знает адреса и контрольные суммы своих модулей — они вшиты в него при сборке — и загружает модуль только той же версии. Если загруженный файл объявляет другую версию, ядро его отбрасывает. Симптом частичный: просмотры страниц, идентификация и автосбор работают, а записи сессий, диагностика и выбор элементов молча не включаются.

Отдельный подвид: у совместимого адреса модули запрашиваются по версионному пути своей версии. Если браузер держит в кэше вчерашнюю копию /v1/t.js, она попросит модули прежней версии, а установка отдаёт только текущую — и получит 404.

Как проверить. В сетевой панели посмотрите запросы файлов replay.js, diagnostics.js, picker.js:

Что видно Диагноз
код 404 запрошена версия, которой в раздаче нет
сообщение про integrity в консоли файл модуля из другой версии
код 200, но записей и диагностики нет версия внутри модуля не равна версии ядра
запросов нет вовсе возможность выключена настройками проекта или согласием

Полезная проверка адреса: ядро ищет модули рядом с собой только тогда, когда его собственный путь заканчивается на sdk/browser/0.6.0/tracker.js. Если файл переименован или каталог «уплощён», модули начнут запрашиваться от корня домена по пути /v1/sdk/browser/0.6.0/, где их нет.

Безопасное исправление. Обновляйте набор целиком: манифест и все четыре файла одной версии, в каталог этой версии, сохраняя структуру путей. Пока новый каталог не проверен, старый не удаляйте — тогда возврат к прежней версии сводится к правке адреса и суммы в теге.

Если не помогло. Если расхождение вызвано кэшированной копией совместимого адреса, оно проходит само в пределах суток, когда кэш обновится. Ускорить и одновременно застраховаться от повторения можно единственным способом — перейти на версионный адрес.

Манифест не соответствует файлам

Вероятная причина. Частичное копирование: скачали не все файлы, скачали в разное время из разных версий, либо докачали один файл поверх старого каталога. Второй вариант — файл повреждён при переносе: обрыв загрузки без проверки кода ответа, копирование в текстовом режиме, преобразование переводов строк.

Как проверить. Сверьте каждый файл со своим полем в манифесте. Проверка идёт по шестнадцатеричным суммам и не требует ничего, кроме openssl и python3:

DIR=public/vendor/actionpulse/v1/sdk/browser/0.6.0

for name in tracker replay diagnostics picker; do
  key=$name
  [ "$name" = "tracker" ] && key=core
  expected=$(python3 -c "import json;print(json.load(open('$DIR/manifest.json'))['assets']['$key']['sha384'])")
  actual=$(openssl dgst -sha384 "$DIR/$name.js" | awk '{print $NF}')
  if [ "$expected" = "$actual" ]; then echo "ok   $name"; else echo "FAIL $name"; fi
done

Дополнительная проверка «тот ли это файл, что отдаёт источник»: у каждого версионного файла заголовок ETag равен его сумме SHA-256, поэтому

curl --silent --head https://YOUR_ACTIONPULSE_HOST/v1/sdk/browser/0.6.0/tracker.js | grep -i '^etag'
openssl dgst -sha256 tracker.js | awk '{print $NF}'

должны дать одно и то же шестнадцатеричное значение.

Безопасное исправление. Любое FAIL — повод остановить выкладку, а не «перекачать и посмотреть». Скачайте набор заново в новый пустой каталог, проверьте суммы там и только после успешной проверки переключайте тег.

Если не помогло. Скачивайте с проверкой кода ответа, иначе в файл попадёт страница ошибки вашего прокси:

curl --fail --silent --show-error "$SRC/tracker.js" -o "$DST/tracker.js"

Флаг --fail превращает ответ об ошибке в ненулевой код возврата вместо тихой записи мусора в файл.

После обновления версии страница осталась на прежней

Вероятная причина. Обновление не доехало до разметки, которую получает посетитель. Порядок вероятности: контейнер тег-менеджера не опубликован; страница отдаётся из кэша страниц или CDN и содержит старый тег; шаблон обновлён в одной ветке, а раздаётся другая; сервис-воркер держит копию HTML; изменение внесено только в одну из нескольких точек подключения (например, на основном сайте, но не в оформлении заказа).

Как проверить. Смотрите то, что реально отдаёт сервер, а не то, что в шаблоне:

# подставьте адрес своей страницы, а не адрес установки ActionPulse
curl --silent https://example.com/ | grep -o 'sdk/browser/[0-9.]*/tracker\.js'

Запрашивать нужно именно свою публичную страницу: вам нужен тег в той разметке, которую получает посетитель. Затем сравните с pp.trackerVersion в браузере: если разметка новая, а версия старая, дело в кэше файла, если разметка старая — в раздаче страниц.

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

Если не помогло. Убедитесь, что после переключения версии события действительно идут: запрос на /v1/track с ответом 202. Порядок безопасного обновления — сначала подтвердить, что новая версия работает, и только потом убирать прежний каталог.

Что проверить

  1. Значение integrity в теге совпадает с assets.core.integrity из манифеста своей установки.
  2. Сумма каждого раздаваемого файла совпадает с полем sha384 из манифеста той же версии.
  3. Адрес в теге и версия в адресах модулей — одни и те же.
  4. pp.trackerVersion в браузере равен ожидаемой версии.
  5. Заголовок ETag у файла из источника совпадает с SHA-256 вашей копии.
  6. Раздача отдаёт байты без преобразований, а crossorigin="anonymous" стоит рядом с integrity при загрузке с другого домена.

Полный порядок раздачи файлов со своего домена — в self-hosted установке, инструменты диагностики — в диагностике отправки.