Перезапись nginx для pushState-URL
Я пытаюсь получить nginx
для работы с моей обработкой URI, основанной на pushState
, которую backbone.js
управляет для меня в приложении Javascript.
Прямо сейчас доступ к URI с одним уровнем, например. example.com/users
работает хорошо, но не на двухуровневом или более глубоком URI, например example.com/users/all
, который упоминается в документации на базовую станцию :
Например, если у вас есть маршрут /documents/ 100, ваш веб-сервер должен иметь возможность обслуживать эту страницу, если браузер посещает этот URL-адрес непосредственно
Итак, далеки от знакомства с параметрами перезаписи nginx, я все еще уверен, что могу сделать что-то вроде rewrite ^ /index.html;
, чтобы перенаправить все на мой index.html
, но проиграть любые возможные статические файлы (изображения, javascript и css), хранящиеся на том же сервере, к которому я должен иметь доступ.
Итак, что мне делать вместо приведенной ниже текущей конфигурации, чтобы сделать эту работу?
server {
listen 80;
server_name example.com;
location / {
root /var/www/example.com;
try_files $uri /index.html;
}
}
Ответы
Ответ 1
Вот что я сделал с моим приложением. Каждый маршрут, заканчивающийся на "/" (кроме корня it self), будет обслуживать index.html
:
location ~ ^/.+/$ {
rewrite .* /index.html last;
}
Вы также можете использовать префикс своего маршрута:
Backbone.history.start({pushState: true, root: "/prefix/"})
а затем:
location ~ ^/prefix/ {
rewrite .* /index.html last;
}
Или определите правило для каждого случая.
Ответ 2
В итоге я решил использовать это решение:
server {
listen 80;
server_name example.com;
root /var/www/example.com;
# Any route containing a file extension (e.g. /devicesfile.js)
location ~ ^.+\..+$ {
try_files $uri =404;
}
# Any route that doesn't have a file extension (e.g. /devices)
location / {
try_files $uri /index.html;
}
}
Таким образом, по крайней мере, я по-прежнему получаю надлежащие 404 ошибки, если файл не найден.
Ответ 3
Мне это удалось:
#set root and index
root /var/www/conferences/video/;
index index.html;
#route all requests that don't serve a file through index.html
location / {
if (!-e $request_filename){
rewrite ^(.*)$ /index.html break;
}
}
Ответ 4
С клиентскими путями приложений:
/
/foo
/foo/bar
/foo/bar/baz
/foo/bar/baz/123
/tacos
/tacos/123
Использование:
server {
listen 80;
server_name example.com;
root /var/www/example.com;
gzip_static on;
location / {
try_files $uri $uri/ /index.html;
}
# Attempt to load static files, if not found route to @rootfiles
location ~ (.+)\.(html|json|txt|js|css|jpg|jpeg|gif|png|svg|ico|eot|otf|woff|woff2|ttf)$ {
try_files $uri @rootfiles;
}
# Check for app route "directories" in the request uri and strip "directories"
# from request, loading paths relative to root.
location @rootfiles {
rewrite ^/(?:foo/bar/baz|foo/bar|foo|tacos)/(.*) /$1 redirect;
}
}
В то время как @ответ Adam-Waite работает для корня и путей на корневом уровне, используя, если внутри контекста местоположения считается антипаттерн, часто наблюдаемый при преобразовании Apache стиль. Смотрите: http://wiki.nginx.org/IfIsEvil.
Другие ответы не охватывают маршруты с глубиной каталога для моего варианта использования в аналогичном приложении React, используя включенную реакцию-маршрутизатор и HTML5 pushState. Когда маршрут загружается или обновляется в "каталоге", например example.com/foo/bar/baz/213123
, файл index.html ссылается на файл js по относительному пути и разрешает example.com/foo/bar/baz/js/app.js
вместо example.com/js/app.js
.
Для случаев с глубиной каталога за пределами первого уровня, например /foo/bar/baz
, обратите внимание на порядок каталогов, объявленных в директиве @rootfiles: сначала должны пройти самые длинные пути, а затем следующий более мелкий путь /foo/bar
и наконец /foo
.
Ответ 5
Так как для этого случая может быть ajax-запрос api,
server {
listen 80;
server_name example.com;
root /var/www/example.com;
# Any route containing a file extension (e.g. /devicesfile.js)
location ~ ^.+\..+$ {
try_files $uri =404;
}
# Any route that doesn't have a file extension (e.g. /devices)
location / {
try_files $uri /index.html;
}
# The location block above provides the shortest prefix, of length one,
# and so only if all other location blocks fail to provide a match,
# this block will be used.
# Ajax api starts with /v1/ will be proxied
location /v1/ {
proxy_pass http://proxy;
}
}