Opencart имеет такую структуру URL:
http://example.com/index.php?route=common/home
http://example.com/index.php?route=account/register
http://example.com/index.php?route=checkout/cart
http://example.com/index.php?route=checkout/checkout
... и я хочу избавиться от строки из index.php?route=
до первого /
, регулярное выражение для этого index.php\?route\=[^\/]*\/
, поэтому желаемый URL-адрес будет, например, http://example.com/checkout
.
Я попытался:
location @opencart {
rewrite index.php\?route\=[^\/]*\/ / last;
rewrite ^/(.+)$ /index.php?_route_=$1 last;
}
а также пробовал:
location / {
if ($query_string ~ "^route=common/home$"){
rewrite ^/index\.php$ http://www.example.com? redirect;
}
}
... но пока не повезло, я все еще вижу route=common/home
в URL-адресах.
Это моя текущая конфигурация Nginx:
location / {
try_files $uri @opencart;
}
location @opencart {
rewrite ^/(.+)$ /index.php?_route_=$1 last;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ~* \.(engine|inc|info|install|make|module|profile|test|po|sh|.*sql|theme|tpl(\.php)?|xtmpl)$|^(\..*|Entries.*|Repository|Root|Tag|Template)$|\.php_ {
deny all;
}
location ~ /\.ht {
deny all;
}
location /image/data {
autoindex on;
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location ~* \.(?:jpg|jpeg|gif|bmp|ico|png|css|js|swf)$ {
expires max;
access_log off;
}
В try_files
Директива должна обрабатывать большую часть работы. У меня не установлен OpenCart, поэтому следующее не проверено. Хотя это может быть хорошей отправной точкой. В $uri
переменная будет включать ведущую /
, который исключен правилами .htaccess, которые я видел. Если это проблема, ее можно исключить, приложив еще немного усилий.
location = /sitemap.xml {
try_files /index.php?route=feed/google_sitemap =404;
}
location = /googlebase.xml {
try_files /index.php?route=feed/google_base =404;
}
try_files $uri $uri/ /index.php?_route_=$uri;
Правила перезаписи могут переводить маршруты во входящих запросах из хорошей версии в версию с соответствующим заклинанием на основе index.php, но похоже, что это вопрос о сгенерированном HTML, отправленном в ответах, который по-прежнему создается с помощью заклинания index.php ? Чтобы изменить маршруты на основе index.php в ответах, отправленных браузеру, попробуйте nginx 'ngx_http_sub_module:
http://nginx.org/en/docs/http/ngx_http_sub_module.html
Что-то вроде:
sub_filter '/index.php?route=' '';
sub_filter_once on;
в сочетании с перезаписью может хватить.
URL-адреса веб-страниц, которые вы получаете от OpenCart, генерируются программным обеспечением OpenCart. Вам нужно найти удобные URL-адреса в его конфигурации и включить их.
Затем вы можете применить соответствующий rewrite
rules в nginx, чтобы входящие запросы правильно направлялись в OpenCart.
Следующее выглядит хорошо?
map $arg_route $_dest { default "/"; "~*^(?:[^/]*)(?<dest>/.*)" $dest; }
server {
location / {
try_files $uri @opencart;
}
location @opencart {
rewrite ^(?i)/index.php$ $_dest? last;
}
}
Это может работать, а может и не работать, в зависимости от того, насколько «умным» ваш апстрим Opencart считает это.
Идея, согласно https://stackoverflow.com/questions/21687288/nginx-redirect-loop-remove-index-php-from-url/21813759#21813759, выдавать редиректы только если index.php
появляется в исходном запросе от пользователя (в $request_uri
), но не если он просто присутствует как часть внутренней маршрутизации (в $uri
). Например, может показаться, что приведенный ниже фрагмент приведет к возникновению цикла, но этого не должно быть.
rewrite ^/([a-z]+/[a-z]+)$ /index.php?route=$1 last;
if ($request_uri ~ ^/index.php?route=([a-z]+/[a-z]+)$) { return 301 /$1; }
В качестве альтернативы, если ваша обработка через try_files
уже могу поймать 404
, и перенаправить его на Opencart (например, если URL-адреса без index.php?route=
часть уже работает так, как задумано), то все, что вам нужно, это следующее:
if ($request_uri ~ ^/index.php?route=(.*)$) { return 301 $1; }