После переноса одного сайта на CSM Битрикс работающего на хостинге с apache на другой хостинг с вебсервером nginx, все правила в .htaccess стали непригодны. Благо их было не много. Разобравшись как и где прописать подобные правила для nginx, стандартное правило для скрипта обработки адресов 1C Битрикс (urlrewrite.php) нашел достаточно быстро:
.htaccess
nginx.conf
На 2 других правила потратил времени чуть больше, т.к. найденные в сети примеры просто не работали или не подходили:
1. Редирект с поддомена www
2. Редирект с добавлением слэша "/" в конце строки при обращении к адресам без слеша.
Для настройки пришлось почитать документацию по nginx подробнее.
.htaccess
.htaccess
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !/bitrix/urlrewrite.php$
RewriteRule ^(.*)$ /bitrix/urlrewrite.php [L]
nginx.conf
f (!-e $request_filename) {
rewrite ^(.*)$ /bitrix/urlrewrite.php last;
}
На 2 других правила потратил времени чуть больше, т.к. найденные в сети примеры просто не работали или не подходили:
1. Редирект с поддомена www
2. Редирект с добавлением слэша "/" в конце строки при обращении к адресам без слеша.
Для настройки пришлось почитать документацию по nginx подробнее.
.htaccess
#Remove 'www'
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^ http://%1%{REQUEST_URI} [R=301,L]
#Add '/'
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} (.*/[^/.]+)($|\?)
RewriteRule .* %1/ [R=301,L]
По www хотелось получить универсальное правило как было в .htaccess, не привязанное к названию конкретного домена. В итоге получил такой результат:
nginx.conf
#Remove 'www'
#Хост соответствует регулярному выражению
if ($http_host ~* "^www\.(.+)$"){
#Запоминаем хост без www из предыдущего выражения в переменной $nowww
set $nowww $1;
#Делаем 301 редирект (permanent)
#В $request_uri - адрес без хоста со всеми GET параметрами
#После $request_uri добавляем '?' чтобы GET параметры
#не добавились дважды (по умолчанию)
rewrite ^ http://$nowww$request_uri? permanent;
}
#Add '/'
#Это не существующий файл/каталог...
if (!-e $request_filename){
#301 редирект с добавлением '/'
rewrite (.*/[^/.]+)($|\?) $1/ permanent;
}
В моем случае я просто вставил правила в нужные существующие директивы файла nginx.conf. Правила для nginx должны быть указаны внутри директивы конфигурации server:
server {
....
if (!-e $request_filename){
rewrite (.*/[^/.]+)($|\?) $1/ permanent;
}
....
}
P.S. Полученного опыта недостаточно чтобы сравнивать apache и nginx. О плюсах и минусах можно найти материалы в сети, но один неудобный момент при использовании nginx.conf - нужно выполнять перезапуск сервиса nginx после каждого изменения конфигурации.
Bonus: Встроенные переменные nginx которые можно использовать при конфигурировании:
$args, эта переменная равна аргументам в строке запроса; $arg_name, эта переменная равна аргументу name в строке запроса; $binary_remote_addr, эта переменная равна адресу клиента в бинарном виде, длина её значения всегда 4 байта; $content_length, эта переменная равна строке "Content-Length" в заголовке запроса; $content_type, эта переменная равна строке "Content-Type" в заголовке запроса; $cookie_name, эта переменная равна cookie name; $document_root, эта переменная равна значению директивы root для текущего запроса; $document_uri, то же самое, что и $uri; $host, эта переменная равна строке "Host" в заголовке запроса или имени сервера, на который пришёл запрос, если этой строки нет; $hostname, эта переменная равна имени хоста; $http_name, эта переменная равна строке name в заголовке запроса; $is_args, эта переменная равна "?", если в строке запроса есть аргументы, и пустой строке, если их нет; $limit_rate, эта переменная позволяет установить ограничение скорости соединения; $pid, эта переменная равна номеру рабочего процесса; $request_method, эта переменная равна методу запроса, обычно это "GET" или "POST"; $remote_addr, эта переменная равна адресу клиента; $remote_port, эта переменная равна порту клиента; $remote_user, эта переменная равна имени пользователя, используемого в Basic аутентификации; $realpath_root, эта переменная равна значению директивы root для текущего запроса, при этом все символические ссылки преобразованы в реальные путь; $request_filename, эта переменная равна пути к файлу для текущего запроса, формируемому из директив root или alias и URI запроса; $request_body, эта переменная содержит тело запроса. Значение переменной появляется в location'ах, обрабатываемых директивами proxy_pass и fastcgi_pass. $request_body_file, эта переменная равна имени временного файла, в котором хранится тело запроса. По завершению работы файл необходимо удалить. Для того, чтобы тело запроса клиента всегда записывалось в файл, нужно указать client_body_in_file_only on. При передаче имени в проксированном запросе или в запросе к FastCGI-серверу следует запретить передачу самого тела директивами "proxy_pass_request_body off" или "fastcgi_pass_request_body off" соответственно. $request_uri, эта переменная равна полному первоначальному URI вместе с аргументами; $query_string, то же самое, что и $args; $scheme, эта переменная равна схеме запроса — "http" или "https"; $server_protocol, эта переменная равна протоколу запроса, обычно это "HTTP/1.0" или "HTTP/1.1"; $server_addr, эта переменная равна адресу сервера, на который пришёл запрос. Как правило, для получения значения этой переменной делается один системный вызов. Для того, чтобы избежать системного вызова, нужно указывать адреса в директивах listen и использовать параметр bind; $server_name, эта переменная равна имени сервера, на который пришёл запрос; $server_port, эта переменная равна порту сервера, на который пришёл запрос; $uri, эта переменная равна текущему URI в запросе, он может отличаться от первоначального, например, при внутренних редиректах или при использовании индексных файлов.
Комментариев нет:
Отправить комментарий