Несколько условий для перезаписи Nginx
Я пытаюсь найти лучший способ переписать это правило, чтобы оно работало на nginx:
RewriteCond %{REQUEST_URI} !^/clip-art/.*$
RewriteCond %{REQUEST_URI} !^/Clip-Art/.*$
RewriteCond %{REQUEST_URI} !^/cgi-bin/.*$
RewriteCond %{REQUEST_URI} !^/images/.*$
RewriteCond %{REQUEST_URI} !/invitation/
RewriteCond %{REQUEST_URI} !/designer/
RewriteRule ^/(.*)/(.*)/(.*)/(.*)$ /clip-art/$1/$2/$3/$4 [r=301,nc,l]
Я знаю, что могу сделать что-то вроде:
if ($request_uri !~ "/designer") {
rewrite ^/(.*)/(.*)/(.*)/(.*)$ /clip-art/$1/$2/$3/$4 permanent;
}
Но очевидно, что это работает только с одним из имен папок. Как мне заставить его работать с несколькими именами папок?
2 ответа
Регулярные выражения относительно неэффективны и, как правило, не приветствуются в конфигурациях Nginx, когда других методов будет достаточно. Здесь есть несколько случаев, которые не требуют регулярных выражений:
location /clip-art/ {
# ...
}
location /Clip-Art/ {
# ...
}
location /images/ {
# ...
}
location /cgi-bin/ {
# ...
}
Если вы просто обслуживаете статические изображения хотя бы из трех из них, мы можем сделать это еще проще. ^~
Префикс означает, что эти правила будут иметь приоритет над правилами на основе регулярных выражений, которые в противном случае имели бы приоритет. Хотя это имеет много применений, оно может выступать в качестве функции безопасности при работе с каталогами, содержащими только статические ресурсы. Если кому-то удастся загрузить файл PHP или какой-либо другой исполняемый код, который обычно обрабатывается местоположением регулярного выражения, местоположение перед регулярным выражением (с ^~
), и файл не будет выполнен. Я также опустил типичный $uri/
потому что это не совсем применимо к статическим каталогам ресурсов.
location ^~ /clip-art/ { try_files $uri =404; }
location ^~ /Clip-Art/ { try_files $uri =404; }
location ^~ /images/ { try_files $uri =404; }
location /cgi-bin/ {
# ...
}
Что касается остальных условий, Nginx спроектирован так, чтобы соответствовать, начиная с начала каждого URI. В идеале вы можете обрабатывать подобные сценарии в своем приложении, а не в Nginx. Однако в этом конкретном случае относительно эффективное регулярное выражение может быть написано:
rewrite "^((?:/(?!designer|invitation)[^/]+){4})/?$" /clip-art$1 permanent;
https://stackoverflow.com/questions/406230/regular-expression-to-match-a-line-that-doesnt-contain-a-word содержит пример использования регулярных выражений для поиска строк, которые не содержат определенных слов.
Используйте этот подход регулярных выражений в вашем location
директива, а затем использовать ваш rewrite
заявление внутри location
блок.
Кроме того, я предлагаю вам использовать .+
(одно или несколько совпадений) вместо .*
(ноль или более совпадений) в качестве символа подстановки в rewrite
директивы.