Почему сервер может отдавать разные версии файла
Что проверяют
Умеете ли вы локализовать классический баг «у меня воспроизводится, у тебя нет», не заглядывая в код. Это про понимание слоёв между браузером и приложением и про то, какие проверки вы придумаете, чтобы гипотеза превратилась в факт для баг-репорта.
Как отвечать
Идите сверху вниз, от клиента к серверу:
- кэш браузера: файл взят из памяти или с диска по заголовкам
Cache-ControlиETag, обновления на сервере клиент просто не заметил; - промежуточные кэши: CDN, корпоративный прокси, кэш провайдера. Пользователи приходят в разные точки присутствия, и сброс кэша мог дойти не всюду;
- несколько экземпляров приложения за балансировщиком: во время выката часть уже новая, часть старая, и ответ зависит от того, куда попал запрос. То же самое при канареечном выкате и при A/B, только там маршрут выбирается осознанно, по куке или заголовку;
- разные окружения и адреса: стенд, прод, зеркало, старый домен с переадресацией;
- сборка: имена файлов с хэшем содержимого, старый HTML тянет старые ресурсы, пока не обновится сам.
Проверять надо фактами: запросить файл через curl -I и сравнить ETag, Last-Modified, Age и заголовки CDN, повторить с обходом кэша, сверить контрольную сумму тела, посмотреть, какой экземпляр ответил, если он проставляет свой идентификатор. Всё это идёт в баг-репорт целиком.
Где спотыкаются
Останавливаются на словах про кэш и не проверяют. Кэш это гипотеза, а подтверждает её сравнение заголовков и тела ответа, а не перезагрузка страницы с очисткой.
Проверяют из своего браузера с открытой вкладкой и включёнными расширениями. Чистая проверка это curl или приватное окно с отключённым кэшем, иначе вы измеряете своё состояние, а не поведение сервера.
Заводят дефект без адреса, времени и заголовков ответа. Расхождение версий живёт минутами: пока задача дойдёт до разработчика, выкат закончится, и её закроют как невоспроизводимую.