Дублюється виклик коду на бекенді
Нещодавно на роботі натрапив на цікавий кейс — функція на бекенді відпрацьовує двічі, а то й більше, хоча користувач натискає кнопку лише один раз, тобто з фронта не бек запит відправляється лише один раз. Як таке взагалі можливо?
👉 Отже, у нас є:
- У Network лише один запит
- Сам запит падає через
4–6 хвилин з помилкою 408 Request Timeout - Юзер не взаємодіє зі сторінкою після кліку
- Вкладка не оновлюється
- В режимі incognito проблема присутня
- Браузер Chrome
- Застаріла версія Node та Express
- GET-запит
Вже здогадалися, що це таке? Ні? Це був Hidden retry!
Hidden retry — це механізм, при якому браузер автоматично повторює HTTP-запит, але цей повтор не відображається в DevTools. У результаті бекенд отримує кілька однакових запитів, хоча з боку фронтенду здається, що виклик був лише один.
👉 Як це працює
- Браузер відправляє HTTP-запит
- Бекенд його довго обробляє
- Сервер (Node) розриває з’єднання через ~120 секунд (дефолтний server.timeout)
- Сам код на сервері продовжує виконуватись
- Браузер не отримує коректної відповіді довгий час
- Браузер вирішує, що запит не завершився і повторює його
👉 Чому це виникає
Ключова причина — стандартні таймаути у старих версіях Node: server.timeout = 120000 ms (2 хвилини). Після спливу цього часу сервер розриває з’єднання, але сам обробник не зупиняється.
У новіших версіях Node логіку таймаутів переглянули, однак така поведінка тепер просто проявляється по-іншому.
Отже, якщо ваш запит виконується довше двох хвилин, то не виключено, що запит може виконатися більше одного разу.
4 коментарі
Додати коментар Підписатись на коментаріВідписатись від коментарівВелкам ту реальний світ розробки, де сервер не має довіряти запитам клієнтів за замовчуванням.
А як тоді з цим жити?
Якщо коротко: робити нормальний бекенд. Наявність безпекової бази поведінки запитів з цієї сторони, виключає подібний кейс апріорі
Ще спробуй потестувати RDNS