Правило переписывания для nginx (Opencart)

Вопрос или проблема

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

Описание решения

  1. Включение "дружественных URL" в Opencart:
    Убедитесь, что у вас включена функция "ЧПУ" (человекопонятные URL) в настройках Opencart. Это позволит автоматически генерировать корректные URL при выводе страниц.

  2. Конфигурация 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.

Дополнительные рекомендации

  1. Кэширование и оптимизация: Подумайте о добавлении кеширования для статических ресурсов (изображений, CSS, JS), чтобы улучшить производительность сайта.
  2. Проверка на ошибки: После внесения изменений обязательно протестируйте конфигурацию на наличие синтаксических ошибок командой nginx -t.
  3. SEO и редиректы: Убедитесь, что редирект работает корректно, чтобы не потерять существующий трафик по старым URL. Используйте временные, а не постоянные редиректы, если необходимо.

Следуя представленным шагам и рекомендациям, вы сможете создать чистую и оптимизированную структуру URL для вашего OpenCart на Nginx, что улучшит удобство пользователя и положительно скажется на SEO.

Оцените материал
Добавить комментарий

Капча загружается...