Как настроить Nginx для обслуживания всегда одного статического файла для всех местоположений, соответствующих шаблону?

#nginx #react-router

#nginx #react-router

Вопрос:

У меня есть одно приложение laravel, обслуживаемое через nginx, и другое приложение только с react, которое создает статический сайт, который использует только маршрутизацию на стороне клиента react-router.

Пока все хорошо, теперь я хочу добиться следующего:

все URL-адреса с шаблоном domain.com/admin /[whateverhere] должен быть предоставлен следующий статический HTML-файл

/var/www/html/admin_app/public/index.html (приложение статического администратора react) вместо того, чтобы обрабатываться

/var/www/html/users_app/public/index.php (приложение laravel)

Это моя конфигурация nginx только для этой части, которая не работает, но возвращает 404:

    location /admin/ {
      root /var/www/html/admin_app/public;
      index index.html;
      try_files $uri index.html;
    }
 

Остальная часть конфигурации — это просто ssl и основной домен.

Я не хочу, чтобы приложение laravel обрабатывало маршруты /admin / projects / admin / users, но я хочу, чтобы все они отправлялись только в этот файл index.htlm, который является статическим приложением react, только с маршрутизатором на стороне клиента.

Проверяя внешний вид nginx, я вижу, что он пытается прочитать несуществующий HTML-файл! не тот, который я указываю в /var/www/html/admin_app/public/index.html

  2020/12/01 15:30:31 [error] 6#6: *8 open() "/etc/nginx/htmlindex.html" failed (2: No such file or directory),
 

Я понятия не имею, почему nginx пытается открыть это /etc/nginx/htmlindex.html досье…

Комментарии:

1. Ваш /index.html термин нуждается в начале / и не может быть конечным параметром. Использовать: try_files /index.html =404;

2. Отлично ! Это работает очень хорошо, так как на первом шаге все обслуживают index.html . Теперь у меня вторая проблема, то есть для js, изображений и других файлов, которые мне нужно обслуживать вместо index.html . Как я могу использовать одно правило для этого? Теперь, что происходит, это, например domain/admin/js/t.js возвращается содержимое index.html . Идея в том, что index.html должны быть возвращены только для таких маршрутов, как domain / admin / posts / 33 и так далее, Файлы должны быть возвращены из реального содержимого файла

3. Все ли файлы ресурсов /var/www/html/admin_app/public загружены и доступны с помощью URI, начинающегося с /admin/ ?

4. @RichardSmith да, именно они запрашиваются, как будто domain/admin/static/js/main.js они расположены в /var/www/html/admin_app/public/static/js / static/ css и так далее, в то время как индекс находится только в public/index.html вместе с favicon и другими вещами там

5. Пример, как index.html запрашивает фрагмент веб-пакета: https://domain.dev/admin/static/js/main.119be1ce.chunk.js и в настоящее время index.html возвращается для всего, а также для этого результата скрипта

Ответ №1:

Есть два возможных решения…

Во-первых, используя регулярное выражение location с root try_files директивой and:

 location ~ ^/admin(/.*)$ {
    root /var/www/html/admin_app/public;
    try_files $1 /index.html =404;
}
 

Регулярное выражение location вычисляется по порядку, поэтому размещение в файле конфигурации имеет большое значение. Поместите рядом с началом server блока, чтобы избежать нежелательных побочных эффектов. Подробности см. В Этом документе.

Обратите внимание, что =404 никогда не достигается, он просто существует, /index.html это не последний параметр try_files инструкции. Подробности см. В Этом документе.


В качестве альтернативы, используя префикс location с alias директивой:

 location ^~ /admin/ {
    alias /var/www/html/admin_app/public/;
    if (!-e $request_filename) { rewrite ^ /admin/index.html last; }
}
 

И location значение, и alias значение должны заканчиваться на a / , или ни одно из них не должно заканчиваться на a / .

Директивы alias and try_files плохо работают вместе из-за этой долгосрочной проблемы, отсюда if и блок. См. Это предупреждение об использовании if внутри location блока.

Комментарии:

1. Отлично, это почти там!!! Ресурсы работают нормально, индекс работает нормально, все маршруты, не относящиеся к файлам, отправляются в index.html . Проблема: также URL-адреса, подобные domain/api/admin/approve-posts этому, все еще обрабатываются этим блоком местоположений. Мне нужны только URL-адреса, которые domain/admin/.* должны обрабатываться этим блоком, а URL-адреса, которые не имеют непосредственно после домена ` / admin`, должны обрабатываться приложением laravel, как и раньше, потому что теперь они сломались и возвращают 404, например, теперь domain/api/admin/approve-post возвращает 404 обрабатывается этим новым блоком location, вместо этого должен обрабатыватьсяблок laravel, как и раньше

2. Ни один из location блоков в моем ответе не будет соответствовать URI, начинающемуся с /api/admin/ . Если эти URI перенаправляются, это происходит в другом месте вашей конфигурации.

3. Я перезапустил прокси, теперь он работал корректно со вторым вариантом, используя только совпадающие с псевдонимом данные, начинающиеся с /admin непосредственно после домена, и все остальные, такие как /api/admin или что-то еще /admin, обрабатываемые следующими местоположениями приложения laravel. Большое спасибо, отмечен как ответ отличное решение