Недавно мы перешли на Nginx с Apache, под apache это было очень просто, просто поместите кое-что в .htaccess и готово.
RewriteEngine on
RewriteBase /
# only rewrite if the requested file doesn't exist
RewriteCond %{REQUEST_FILENAME} !-s
# pass the rest of the request into index.php to handle
RewriteRule ^(.*)$ /index.php/$1 [L]
Вышеуказанное отлично подходит для очистки URL-адреса и позволяет index.php обрабатывать все запросы. но в Nginx нам нужно было переписать каждый уникальный URL-адрес в блоке местоположения. Однако это не «автоматический», как apache.
Несколько примеров нашего перезаписываемого блока местоположения
location / {
try_files $uri $uri/ /index.php;
}
location /p {
rewrite ^/p(?:/([a-z_]+))?$ /index.php?p=$1 last;
rewrite ^/p/all_articles/user/(.*)?$ /index.php?p=all_articles&user=$1 last;
try_files $uri $uri/ /index.php;
}
location /about_us {
rewrite ^/about_us /index.php?about_us last;
try_files $uri $uri/ /index.php;
}
location /search {
rewrite ^/search/(.*) /index.php?search=$1;
rewrite ^/search/(.*)/page/(.*)?$ /index.php?search=$1&page=$2 last;
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
приведенное выше хорошо работает с чистым URL-адресом, но когда нам нужно получить страницы, например
/ p / all_articles / пользователь / ABC / page / 2
/index.php?p=all_articles&user=ABC&page=2
мы пробовали
rewrite ^/p/all_articles/user/(.*)/pg(?:/([0-9]+))?$ /index.php?p=all_articles&user=$1&pg=$2 last;
это работает только тогда, когда мы помещаем в отдельный блок местоположения
location /page/all_articles {
rewrite ^/p/all_articles/user/(.*)/pg(?:/([0-9]+))?$ /index.php?p=all_articles&user=$1&pg=$2 last;
try_files $uri $uri/ /index.php;
}
и когда это будет сделано, это не позволит
/ p / all_articles / пользователь / ABC
загружать.
Кроме того, страницы результатов поиска не работали бы вообще.
еще одна проблема, с которой мы столкнулись, находится в папке .htaccess
Order deny,allow
Deny from all
Options -Indexes
В apache это предотвратит любой доступ к этой папке и файлам, кроме скрипта php. Мы попытались,
location /(data|img)/ {
deny all;
return 404;
}
Он блокирует доступ к папке, но, если вы укажете имя файла, он все равно будет работать, например, без отказа в доступе;
/data/backup_01012020.zip в apache .htaccess, только определенным пользователям был разрешен доступ к нему во время регистрации. а за его пределами apache запретит любой доступ. Но даже под nginx он выдает 404 при попытке доступа к / data /. Даже если вы не вошли в систему, он сразу же предоставит файл backup_01012020.zip.
Теперь мы не можем понять, что мы можем сделать, что раньше было пустяком с apache. Наше приложение основано на PHP, а index.php способен обрабатывать все чистые запросы URL. Было бы здорово, если бы Nginx просто передавал все запросы на индекс и позволял ему обрабатывать вместо множества перезаписей и блоков местоположения. Любая помощь была бы замечательной.
Возможно, вас заинтересуют вопросы с перезаписать тег, поскольку он содержит множество вариантов вашей проблемы.
Правило перезаписи вашего Apache:
RewriteRule ^(.*)$ /index.php/$1 [L]
добавляет весь URI запроса к /index.php
. В nginx в дорожка URI (нормализованный) доступен в $ uri переменная. Если вам также нужны аргументы запроса, вы можете использовать $ request_uri вместо.
Таким образом, строгий перевод ваших правил перезаписи будет таким:
location / {
# Size zero static files are served.
# I don't believe that is an issue.
try_files $uri /index.php$request_uri;
}
# If no other .php files are accessible a prefix location of '/index.php/'
# is safer.
location /index.php/ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
# Probably duplicates the contents of fastcgi-php.conf
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# include fastcgi_params;
}
Ваш deny
директива о /(data|img)/
location не работает, так как вы используете совпадение префикса вместо совпадения регулярного выражения:
location ~ ^/(data|img)/ {
# Only one is required
deny all;
# return 404;
}
Решение для перезаписи
location /search {
rewrite ^/search/(.*)/page/(.*)?$ /index.php?search=$1&page=$2 last;
rewrite ^/search/(.*) /index.php?search=$1 last;
try_files $uri $uri/ /index.php;
}
location /p/all_articles {
rewrite ^/p/all_articles/user/(.*)/page(?:/([0-9]+))?$ /index.php?p=all_articles&user=$1&page=$2 last;
rewrite ^/p/all_articles/user/(.*)?$ /index.php?p=all_articles&user=$1 last;
try_files $uri $uri/ /index.php;
}
Заметьте, все, что я сделал, это поменял местами линии. Кредиты для Ричард Смит
Благодаря Петр П. Карвашдля другого решения это может помочь кому-то, чей сценарий на 100% совместим, самостоятельно обрабатывать чистый URL-адрес.
location / {
# Size zero static files are served.
# I don't believe that is an issue.
try_files $uri /index.php$request_uri;
}
# If no other .php files are accessible a prefix location of '/index.php/'
# is safer.
location /index.php/ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
# Probably duplicates the contents of fastcgi-php.conf
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# include fastcgi_params;
}
Вышеупомянутое решение - это способ, пока ваш скрипт работает с чистым URL-адресом на 100%. Здесь вам не нужно помещать 100 блоков местоположения перезаписи, и nginx добавит весь URI запроса в /index.php, что очень интересно и полезно, вероятно, это реальное решение, но в моем случае мой скрипт не был 100 % совместим с этим. Тем не менее, это хорошее, резкое решение.
Soution для предотвращения доступа к папкам, файлам
location ~ ^/(data|img)/ {
# Only one is required
deny all;
# return 404;
}
Кредиты для Петр П. Карваш отметил, что deny all
было что-то переопределено, после чистого блока сервера проблема была решена. Также не забудьте использовать либо deny all;
или return 404;
но не вместе.