Почему axios дублирует POST запросы и как это исправить

    В веб-приложениях на Vue.js 3 с axios и бэкендом на Laravel 8 (Nginx + php-fpm) иногда возникает редкая, но критическая проблема: один клик пользователя приводит к двум одинаковым POST запросам. При этом идентификаторы запросов совпадают, что исключает баг на уровне фронтенд-логики. Рассмотрим основные причины и способы устранения дублирования.

    Почему происходит дублирование POST запросов

    Проблема проявляется на планшетах с Android 14 и Яндекс Браузером при использовании CORS и HTTP/2. Типичная последовательность: OPTIONS (preflight), POST, и ещё один POST через ~1 секунду. Ключевой момент - идентификаторы запросов одинаковы, значит, функция отправки вызывается один раз, но запрос уходит дважды.

    Нестабильность Wi-Fi соединения

    На мобильных устройствах и планшетах беспроводная сеть может быть нестабильной. Если первый POST запрос не получил подтверждения (ACK) от сервера в ожидаемый срок, браузер или axios могут автоматически повторить отправку. Это особенно характерно для HTTP/2, где мультиплексирование потоков иногда приводит к конфликтам при нестабильном соединении.

    Поведение CORS preflight запросов

    При использовании CORS браузер сначала отправляет OPTIONS запрос (preflight). Если сервер отвечает некорректно (например, с задержкой или неверными заголовками), браузер может повторно инициировать всю цепочку: снова OPTIONS, а затем POST. Это редко, но возможно при высоких задержках в сети.

    Особенности Яндекс Браузера на Android 14

    Некоторые браузеры, включая Яндекс Браузер, имеют встроенные механизмы автоматического ретрая запросов при сетевых ошибках. Если первый POST не завершился успешно (например, таймаут), браузер может повторить его, не уведомляя приложение. Это объясняет, почему на бэкенде видны два запроса с одинаковым ID.

    Как диагностировать и исправить дублирование

    Проверка сетевых таймаутов и повторных попыток

    Настройте axios так, чтобы он не выполнял автоматические повторные попытки. Используйте параметр retry: false или установите timeout явно. Пример конфигурации:

    const instance = axios.create({ baseURL: 'https://api.example.com', timeout: 10000, headers: { 'X-Request-ID': generateUUID() } });

    Также отключите автоматические ретраи на уровне браузера (если возможно) или добавьте проверку на стороне сервера по уникальному ID.

    Улучшение обработки CORS на Nginx

    Убедитесь, что ваш сервер корректно обрабатывает OPTIONS запросы. В конфигурации Nginx добавьте:

    location / { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' '*'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,X-Request-ID'; add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain; charset=utf-8'; add_header 'Content-Length' 0; return 204; } }

    Это уменьшит вероятность повторной отправки preflight запроса.

    Использование уникальных идентификаторов и дедупликация

    Поскольку вы уже добавили уникальный ID, реализуйте на бэкенде проверку: если запрос с таким ID уже обработан, игнорируйте дубликат. В Laravel это можно сделать через middleware или кэш (Redis):

    $requestId = $request->header('X-Request-ID'); if (Cache::has('request_' . $requestId)) { return response()->json(['status' => 'duplicate'], 429); } Cache::put('request_' . $requestId, true, 60);

    Это защитит от двойной обработки даже при повторных запросах.

    Отключение HTTP/2 для проблемных клиентов

    Если проблема массовая, временно отключите HTTP/2 на Nginx для мобильных устройств. Хотя это не рекомендуется, это может помочь выявить причину. В конфигурации:

    server { listen 443 ssl http2; # временно убрать http2 }

    После тестирования верните настройки.

    Заключение

    Дублирование POST запросов в связке Vue.js + axios + Laravel чаще всего вызвано нестабильностью сети и автоматическими ретраями браузера. Используйте уникальные идентификаторы с дедупликацией на бэкенде, настройте таймауты и корректно обрабатывайте CORS. Это минимизирует риск повторных запросов.

    Часто задаваемые вопросы