#Что означает и когда возникает ошибка
Решение зависит от архитектуры: для одностраничного приложения допустима передача отсутствующих файлов на index.html, а для PHP-приложения часто нужен внутренний переход на index.php. Нельзя смешивать оба подхода без проверки.
#Причины и как их различить
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Одностраничное приложение управляет маршрутами в браузереПри переходе по ссылке маршрут работает, а при прямом обновлении выдаётся 404 от Nginx. | Вложенный маршрут существует только в JavaScript, физического каталога на диске нет. | Направлять неизвестные пути на index.html при сохранении обработки статических файлов. |
| Серверный PHP-маршрутизатор получает не тот URLФреймворку нужен index.php и строка запроса, но Nginx возвращает 404. | В access.log 404 для /account/settings/, при этом PHP-код не запускался. | Применить конфигурацию front controller именно используемого фреймворка. |
| location или root/alias перекрывают правилоБолее приоритетное регулярное или точное location отрабатывает раньше ожидаемого. | Правило try_files есть в конфигурации, но срабатывает другой блок. | Проверить порядок location и фактический root/alias. |
#Пошаговая диагностика и исправление
- Установите, кто должен обрабатывать URLВозьмите два адреса: рабочий
/и сбойный вложенный, например/account/settings/. Откройте вложенный адрес через меню приложения, затем обновите страницу и откройте тот же URL в новой вкладке. Если после внутренней навигации всё работает, а при обновлении 404 — это типичная проблема маршрутизации. Если 404 выдаёт само приложение даже без обновления, исправление try_files может не помочь. - Выясните тип приложения до правкиПосмотрите документацию сборки сайта или спросите разработчика: React/Vue со статическим index.html, PHP-фреймворк с index.php либо обычные файлы. По SSH проверьте фактический
rootи содержимое публичного каталога безопасной командойls -laпо существующему пути. Не переименовывайте index.php в index.html и не меняйте обработчик PHP для решения 404. - Найдите соответствующий server и locationЗапустите
sudo nginx -Tи найдитеserver_name,root,alias, всеlocation,try_files,error_pageдля домена. Учитывайте, чтоlocation =имеет особый приоритет, а регулярные выражения могут перехватывать запросы. Проверьте именно путь вложенного URL: совпадениеlocation /ещё не означает, что его обслуживает этот блок. - Для статического одностраничного приложения используйте fallbackЕсли это подтверждённый статический SPA, в основном
location /уместна логикаtry_files $uri $uri/ /index.html;. Она сначала проверяет реальный файл/каталог, иначе отдаёт индекс. Перед применением проверьте, что index.html существует внутри верного root. Исключите из такой подстановки API, приватные маршруты и отсутствующие файлы ресурсов, если они должны возвращать честный 404. - Для PHP-фреймворка используйте его правила маршрутизацииЕсли приложение использует front controller, изучите пример конфигурации конкретного фреймворка. Типовой подход
try_files $uri $uri/ /index.php?$query_string;передаёт маршрут в PHP, но корректность требует действующегоlocation ~ \.php$, безопасногоSCRIPT_FILENAMEи правильно настроенного PHP-FPM. Не вставляйте PHP-блок из интернета без учёта действующего root и защиты от исполнения загруженных файлов. - Сохраните копию и примените только подходящий вариантСкопируйте реальный конфигурационный файл с отметкой даты, измените одно правило, выполните
sudo nginx -t. Если тест успешен, выполнитеsudo systemctl reload nginx; если нет — поправьте ошибку, не перезапуская службу. Если 404 сменился на неожиданное выполнение PHP или выдачу приватных файлов, немедленно верните исходный файл и повторите тест и reload. - Проверьте вложенные страницы и настоящие ошибкиОткройте 3–4 вложенных маршрута напрямую и после обновления, проверьте загрузку CSS/JS и API во вкладке «Сеть». Заведомо несуществующий статический ресурс должен сохранять корректный 404, если так предусмотрено архитектурой. Для SPA убедитесь, что JavaScript-приложение показывает собственную страницу «не найдено», не скрывая серверные ошибки.
- Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
#Проверка результата
Успех: прямое открытие и обновление существующего вложенного маршрута дают ожидаемую страницу, а несуществующие пути обрабатываются предсказуемо.
#Если проблема осталась
Сохраните дату, точный URL без паролей и токенов, код ответа, обезличенные строки error.log и access.log за это время и перечень уже сделанных изменений. Сравните работу при обращении через публичный адрес и через внутренний балансировщик, если он есть. Если причину пока не удалось подтвердить, восстановите исходную конфигурацию из копии и передайте эти сведения администратору или разработчику приложения; не меняйте несколько параметров одновременно.