Вопрос или проблема
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;
}
URL-адреса на веб-страницах, которые вы получаете от OpenCart, генерируются программным обеспечением OpenCart. Вам нужно найти удобочитаемые URL в его конфигурации и включить их.
Затем вы можете применить соответствующие правила rewrite
в nginx, чтобы входящие запросы правильно маршрутизировались к OpenCart.
Правила переписывания могут преобразовывать маршруты во входящих запросах из красивой версии в версию с соответствующим вызовом index.php, но, похоже, это вопрос о сгенерированном HTML, отправленном в ответах, который все еще создается с вызовом index.php? Чтобы изменить маршруты на основе index.php в ответах, отправленных браузеру, попробуйте модуль ngx_http_sub модуля nginx:
http://nginx.org/en/docs/http/ngx_http_sub_module.html
Что-то в духе:
sub_filter '/index.php?route=" "';
sub_filter_once on;
в сочетании с переписыванием может быть достаточно.
Директива 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;
Вызывает ли следующее хорошее впечатление?
map $arg_route $_dest { default "https://serverfault.com/"; "~*^(?:[^/]*)(?<dest>/.*)" $dest; }
server {
location / {
try_files $uri @opencart;
}
location @opencart {
rewrite ^(?i)/index.php$ $_dest? last;
}
}
Это может работать или не работать, в зависимости от того, насколько “умным” ваш upstream Opencart считает себя.
Идея состоит в том, чтобы выписывать перенаправления только в том случае, если 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; }
Ответ или решение
Для настройки Nginx с целью изменения структуры URL-адресов Opencart и устранения строки index.php?route=
, необходимо правильно реализовать правила переписывания. Давайте детально рассмотрим, как это сделать.
Задача
Вы хотите преобразовать 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/home
http://example.com/register
http://example.com/cart
Описание решения
-
Включение "дружественных URL" в Opencart:
Убедитесь, что у вас включена функция "ЧПУ" (человекопонятные URL) в настройках Opencart. Это позволит автоматически генерировать корректные URL при выводе страниц. -
Конфигурация Nginx:
Вам необходимо добавить правила переписывания в файл конфигурации Nginx. Используйте следующий конфигурационный фрагмент:
server {
listen 80;
server_name example.com;
root /path/to/your/opencart; # Замените на путь к вашему проекту
index index.php index.html index.htm;
location / {
try_files $uri $uri/ @opencart;
}
location @opencart {
rewrite ^/index.php$ / last; # Убираем index.php
rewrite ^/(.+)$ /index.php?_route_=$1 last; # Переадресация на index.php с использованием _route_
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# Запрет доступа к чувствительным файлам
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;
}
# Остальные настройки, например, обработка изображений, кэша и т.д.
}
Пояснения к конфигурации
- try_files: Этот оператор пытается обслуживать запрашиваемый файл непосредственно. Если файл не найден, управляется управление к этому запросу через block
@opencart
. - location @opencart: Здесь происходит основное преобразование URL. Сначала происходит замена
index.php
, затем все другие маршруты перенаправляются на свой соответствующий адрес внутриindex.php
. - PHP обработка: Секция
location ~ \.php$
настраивает обработку PHP-файлов, обеспечивая верный путь к php-fpm.
Дополнительные рекомендации
- Кэширование и оптимизация: Подумайте о добавлении кеширования для статических ресурсов (изображений, CSS, JS), чтобы улучшить производительность сайта.
- Проверка на ошибки: После внесения изменений обязательно протестируйте конфигурацию на наличие синтаксических ошибок командой
nginx -t
. - SEO и редиректы: Убедитесь, что редирект работает корректно, чтобы не потерять существующий трафик по старым URL. Используйте временные, а не постоянные редиректы, если необходимо.
Следуя представленным шагам и рекомендациям, вы сможете создать чистую и оптимизированную структуру URL для вашего OpenCart на Nginx, что улучшит удобство пользователя и положительно скажется на SEO.