Nginx apache rewrite возможно ли на nginx

Georgich

Новичок
Несколько лет не лез в эту тему, но вот на днях снова окунулся. В итоге nginx, php7 на домашней помойке.
Вопрос собственно вот каков.
Подскажите, есть ли возможность на nginx перенести следующую конструкцию:
RewriteCond %{REQUEST_URI} !((redactor)|(test))
RewriteCond %{REQUEST_URI} !/index.php$
RewriteCond %{REQUEST_FILENAME} (.php|.inc)$
RewriteCond %{REQUEST_METHOD} GET
RewriteRule ^(.*) index.php?http_get=%{REQUEST_FILENAME} [QSA,L]
На апаче очень давно реализовал фишку с прямыми линками (закладками) с ajax, и в случае отключенного js то страницы подгружались не ajax, а по старинке. Но для всей этой работы требовалась именно эта конструкция. Пару дней и так, и эдак пытался завести под nginx, все безполезно.
Может кто подсказку даст?
 

Georgich

Новичок
напиши словами, что хочешь, дай свой конфиг nginx,
Nginx пока с общими конфигами. Пытаюсь когда то написанные правила mod_rewrite применить на nginx.
Код:
RewriteCond %{REQUEST_URI} !/index.php$
RewriteRule ^([a-zA-Z0-9/]+)$ /inc/main.inc?content=$1 [QSA,L]
Иными словами, если запрошеная страница не index.php, то запрос оформляется как /inc/main.inc?content={запрос}
вроде как что то получилось. но не без косяков
в location / { try_files $uri $uri/ /index.php?/inc/main.inc?content=$document_uri; } чтоб обрабатывало не php расширение и в location ~ \.(php|inc)$ {} чтоб работало с php, но чувствую. что это коряво, получается запрос вида /inc/main.inc?content=/{запрос} (со слэшэм).
далее
Код:
RewriteCond %{REQUEST_URI} !/index.php$
RewriteCond %{REQUEST_FILENAME} (.php|.inc)$
RewriteCond %{REQUEST_METHOD} GET
RewriteRule ^(.*) index.php?http_get=%{REQUEST_FILENAME} [QSA,L]
если запрос идет методом GET, то лишь в том случае формируется запрос вида index.php?http_get={запрос}
Код:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php [NC,QSA,L]
если запрос идет не к файлу и не к директории то перенаправляется всё на индексный файл.
Полагаю это тоже реализуется без проблем через try_files.
Вот где то так... С nginx играю всего несколько дней, гугль уже матюгается на меня, поэтому увидев совет воспользоваться гуглем, как то не совсем понятно стало, вроде попросил помощи на старом форуме, который знаю более десятка лет, а меня вышвырнуло снова на гугль...
Вполне вероятно, что решение этой задачи на поверхности, но в силу большого перебоя в практике и первых дней использования nginx никогда раньше его не использовал вообще, что то не могу въехать в тему.
 

MiksIr

miksir@home:~$
У тебя URL ---> /inc/main.inc?content=URL ---> /index.php?http_get=PATH ?
Что за бред. Я по-этому и спросил - опиши словами правила. Твои реврайты, по ходу, не очень логичны.
А почему RewriteCond %{REQUEST_METHOD} GET ? Для POST какие-то отдельные правила?
 

fixxxer

К.О.
Партнер клуба
Забудь про обратную логику реврайтов и напиши нормально - для каких условий что делать.

Вот прямо словами: если условия такие-то, то делать то-то. Первое условие - совпадение URL-а с таким-то префиксом или регулярным выражением. Дальше вложенные любые условия через AND. Обойдись без OR и NOT.
 

Georgich

Новичок
Для POST какие-то отдельные правила
Да, для GET одно, а для POST другое выполнение
Обойдись без OR и NOT.
Эх, завтра после работы попробую без OR и NOT набросать, кажется понимаю, куда ты меня ткнул, спасибо.
В общем завтра опишу и параллельно попробую сам что то сделать.
http://tambur.in/ схема с mod_rewrite замечательно тут работала.
Оговорюсь сразу,что это совершенно ничего общего не имеет с коммерческим проектолм. это лишь игрушка, чисто для себя дорогого, по этой причине и прошу подсказку, а не решение, а то что мне тогда делать то. Это, как в свое время, для моей бабули были кроссворды. жвачка для мозга =)
 

Georgich

Новичок
Прошу прощения, ребята, за пожар, сегодня спокойно пару часов почитав тырнет, почти разобрался.
Код:
location /  {
        if ($request_uri !~ /index.php$)  {
          rewrite ^/([a-zA-Z0-9/]+)$ /inc/main.inc?content=$1;
        }
}
и
Код:
location ~ \.(php|inc|rphp)$ {
            if ($request_method = 'GET')  {
              rewrite ^/(.*) /index.php?http_get=$request_filename break;
            }
}
На деле довольно просто, коль не паникуешь =)
Лёлик!!!! Всё пропало!!!! Всё пропало!!!!!!
(с) бриллиантовая рука
Осталась в общем проблемка с запросом на индексную страницу, но, думаю разберусь.
Спасибо. за участие!

PS. Почти 4 года без практики и совсем отупел. Сегодня разбирал файлики и был чертовски поражен, что это нагромождение классов, шаблонизатора, js написал когда то я. Волосы дыбом встали =)
 

Georgich

Новичок
У тебя URL ---> /inc/main.inc?content=URL ---> /index.php?http_get=PATH ?
Что за бред. Я по-этому и спросил - опиши словами правила. Твои реврайты, по ходу, не очень логичны.
А почему RewriteCond %{REQUEST_METHOD} GET ? Для POST какие-то отдельные правила?
Дело в том, что прямые вызовы работают методом GET, а ajax у меня отправляет запросы POST и из за этого разные запросы. Там повыше ссылка на страницу, где я пытался реализовать на ajax и html 5 закладки с использованием ajax, сохранение истории посещения ajax страниц в браузере с прямым вызовом закладок.
 

fixxxer

К.О.
Партнер клуба
Когда дело доходит до реврайтов типа твоего content, я предпочитаю делать специализированные для сайта fastcgi_params.
Например, в этом случае можно скопировать fastcgi_params в mysite.fcgi, убрать оттуда QUERY_STRING и SCRIPT_FILENAME (если он там есть) и сделать так:

Код:
server {
   server_name mysite ...;
   root .... ;
   location / {
       try_files $uri /start;
   }
   location ~ ^(?<content>/[a-zA-Z0-9/]+)$ {
       fastcgi_param QUERY_STRING content=$content&$args;
       fastcgi_param SCRIPT_FILENAME $document_root/inc/main.inc;
       include /path/to/mysite.fcgi;
       fastcgi_pass ...;
   }
   location = /index.php {
       fastcgi_param QUERY_STRING content=/start&$args;
       fastcgi_param SCRIPT_FILENAME $document_root/inc/main.inc;
       include /path/to/mysite.fcgi;
       fastcgi_pass ...;
   }
   location ~ \.(php|inc)$ {
       fastcgi_param QUERY_STRING $query_string;
       fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
       include /path/to/mysite.fcgi;
       fastcgi_pass ...;
   }
   ...
}
Ну это примерно (до сих пор не уверен, что правильно понимаю твои навороты), только для get. Разные обработчики для get и post - это, конечно, из разряда "не делайте так".

В целом, rewrite вообще лучше не использовать никогда. Единственный "нормальный" вариант использования nginx rewrites - конструкция вида

PHP:
if (...) {
   return ...;
}
С твоими get/post-ами, конечно, придется делать извращения. Лучше бы от такого избавиться в коде.

Обрати внимание, насколько такое "прямое" описание правил понятнее, чем нагромождения реврайтов.
 
Последнее редактирование:

MiksIr

miksir@home:~$
@fixxxer fastcgi_param внутри локейшена перетрет все fastcgi_param из инклуда. Инклуд внутрь каждого локейшена нужно.
 

AnrDaemon

Продвинутый новичок
Просто у тебя заявление было несколько двусмысленное. Но по сути ты прав.
These directives are inherited from the previous level if and only if there are no fastcgi_param directives defined on the current level.
 
Сверху