Несовпадение версий и контрольных сумм
Почему браузер отказывается выполнять файл трекера, откуда берётся старая версия из кэша, как расходятся ядро и модули и как сверить файлы с манифестом своей установки.
На этой странице
Все проблемы этой группы имеют одну природу: байты, которые исполняет браузер, не те, которые ожидает кто-то из участников — тег, ядро трекера или манифест. Диагностика поэтому всегда сводится к сравнению сумм, а не к перезапуску.
Три источника правды
| Источник | Что в нём | Где смотреть |
|---|---|---|
| Манифест версии | размер, 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. Порядок безопасного обновления — сначала подтвердить, что
новая версия работает, и только потом убирать прежний каталог.
Что проверить
- Значение
integrityв теге совпадает сassets.core.integrityиз манифеста своей установки. - Сумма каждого раздаваемого файла совпадает с полем
sha384из манифеста той же версии. - Адрес в теге и версия в адресах модулей — одни и те же.
pp.trackerVersionв браузере равен ожидаемой версии.- Заголовок
ETagу файла из источника совпадает с SHA-256 вашей копии. - Раздача отдаёт байты без преобразований, а
crossorigin="anonymous"стоит рядом сintegrityпри загрузке с другого домена.
Полный порядок раздачи файлов со своего домена — в self-hosted установке, инструменты диагностики — в диагностике отправки.