Возможно, вам придется настроить это в зависимости от того, насколько далеко вы хотите заместить структуру каталогов, но это основная концепция.
Именованное место для первоначального захвата 404 с:
location @notfound {
rewrite (.*) /search$1 last;
}
Именованные местоположения немного ограничивают, поэтому все, что нужно сделать, это добавить /search/
в начало URI, который возвратил 404. Флаг last
указывает Nginx выйти из текущего местоположения и выбрать лучшее местоположение для обработки. запрос основан на переписанном URI, поэтому нам нужен блок, чтобы перехватить это:
location ^~ /search/ {
internal;
rewrite ^/search/(.*)([^a-z0-9\+])(.*)$ /search/$1+$3 last;
rewrite ^/search/(.*)$ /?s=$1 permanent;
}
Директива internal
делает это местоположение доступным только для самого процесса Nginx, любые клиентские запросы к этому блоку возвращают 404.
Первая перезапись изменит последний не текстовый, цифровой или +
символ на +
, а затем попросит Nginx пересмотреть переписанный URI.
Блок местоположения определяется с помощью модификатора ^~
, что означает, что запросы, соответствующие этому местоположению, не будут оцениваться для каких-либо блоков местоположения, определенных регулярным выражением, поэтому этот блок должен продолжать переписывать переписанные запросы.
Как только все несловарные символы пропадут, первая перезапись больше не будет совпадать, поэтому запрос будет передан следующей перезаписи, которая удалит /search
с начала URI и добавит строку запроса.
Мои журналы выглядят так:
>> curl -L -v http://127.0.0.1/users-forum-name.1
<< "GET /?s=users+forum+name+1 HTTP/1.1"
>> curl -L -v http://127.0.0.1/users-forum-name/long-story/some_underscore
<< "GET /?s=users+forum+name+long+story+some+underscore"
Вы поняли идею ..