Преобразование динамических URL в статические

Как  с помощью mod_rewrite преобразовать динамические URL в статические? Эта статья даст ответ, а также прояснит некоторые заблуждения, связанные с этим вопросом.

mod_rewrite не может изменить URL в браузере пользователя

Первое заблуждение: mod_rewrite нельзя использовать для изменения URL, который видит посетитель в адресной строке своего браузера, за исключением возможности использования внешнего редиректа. Но внешний редирект «оголит» динамический URL поисковику, тем самым полностью нарушит нашу цель. Наша цель в том, чтобы сделать статические URL с помощью внутренних преобразований на сервере, не используя внешнего редиректа клиента.

Также важно понимать, что mod_rewrite работает с URL после того, как сервер получил HTTP запрос и до того, как выполнится скрипт или обработается контент. Таким образом, mod_rewrite может менять путь файла на сервере и переменные, связанные с запрошенным URL, но не может изменить контент, отсылаемый сервером.

Как изменить динамический URL на статический

Вот алгоритм, который надо выполнить для создания статических URL на динамическом сайте:

  • Преобразовать все ссылки на всех страницах сайта в статический формат. Обычно это делается путем изменения базы данных или скрипта, который генерирует данные страницы. В некоторых случаях с этой задачей быстро справляется функция PHP — preg_replace().
  • Добавить в файл httpd.conf или .htaccess правила mod_rewrite для внутреннего преобразования статических URL, которые были запрошены клиентом, в динамический вид, необходимый для вызова скрипта генерации контента.
  • Добавить дополнительный код mod_rewrite для прямых запросов клиента на динамический URL и перенаправлять их (внешним редиректом) на соответствующий статический URL. Для этого используется 301 редирект («Постоянно перемещен»), который уведомляет поисковики, что вместо старых динамических URL нужно использовать новые статические. Также внешний редирект перенаправляет посетителей, которые пришли на ваш сайт, используя старую динамическую ссылку из своих закладок.

Рассматривая вышесказанное, можно догадаться, что оба формата: и динамический, и статический URL должны содержать в себе всю информацию, необходимую для преобразования в другой формат. И запомните, что осторожный выбор «дизайна» статических URL в будущем может уберечь вас от многих проблем, а также уменьшить количество циклов процессора, которое может сильно вырасти при неумелой реализации такого преобразования.

Статья по теме:  Яндекс заменяет тИЦ на ИКС — новый показатель качества сайта

Важное предупреждение

В цели этой статьи не входит объяснение принципов работы регулярных выражений и модуля mod_rewrite. Документация по mod_rewrite и множество других мануалов легко доступны для всех желающих.

А попытка же использовать mod_rewrite без полного ознакомления с этой документацией — первый шаг (а часто и последний) к серьезным проблемам. Запомните, что mod_rewrite влияет на конфигурацию вашего сервера и достаточно одной опечатки или логической ошибки, чтобы сделать ваш сайт недоступным для посетителей или быстро понизить ваши рейтинги в поисковых сервисах. А если ваш заработок зависит от сайта, то вам тем более необходимо внимательно изучить всю документацию.
Подробно о регулярных выражения можно прочитать в книге «Освой самостоятельно регулярные выражения».
Ниже приведен пример, который можно использовать в качестве основы при построении собственного решения.

Рабочий пример

Старый динамический формат URL:

index\.php?product=widget&color=blue&size=small&texture=fuzzy&maker=widgetco

Новый статический формат URL:

/product/widget/blue/small/fuzzy/widgetco

Код mod_rewrite, используемый в .htaccess:

# Запуск mod_rewrite
Options +FollowSymLinks
RewriteEngine on
#
# Внутренние преобразования статических URL в динамические
RewriteRule ^product/([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$
/index.php?product=$1&color=$2&size=$3&texture=$4&maker=$5 [L]
#
# Внешний редирект клиента со старых динамических URL на новые статические
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\
/index\.php\?product=([^&]+)&color=([^&]+)&size=([^&]+)&texture=([^&]+)&maker=([^\ ]+)\ HTTP/
RewriteRule ^index\.php$ //example.com/product/%1/%2/%3/%4/%5? [R=301,L]

Заметьте, что слово «product» всегда присутствует и в статическом, и в динамическом формате. В этом случае модулю mod_rewrite проще определить запросы, где необходимо применять приведенные выше правила. Другие методы, такие как проверка на существование файла, также можно использовать, но они менее эффективны и более подвержены ошибкам сравнения.

Различия между использованием .htaccess и httpd.conf

Если вы будете использовать правила mod_rewrite в контейнере <directory> конфигурационного файла httpd.conf, то вам потребуется добавить в регулярные выражения обеих директив RewriteRule слеш (/). Например, придеться изменить «RewriteRule ^index\.php$» на «RewriteRule ^/index\.php$». Также запомните, что вам надо перезапустить сервер, чтобы внесенные изменения в файле конфигурации начали действовать.

Как это работает

  • Посетитель использует браузер для просмотра одной из ваших страниц
  • Посетитель кликает по ссылке <a rel=»nofollow» href=»/product/gizmo/red/tiny/furry/gizmocorp»>Tiny red furry gizmos by GizmoCorp!</a>
  • С вашего сервера браузер запрашивает виртуальный файл //example.com/product/gizmo/red/tiny/furry/gizmocorp
  • Вызывается mod_rewrite и первое правило переформировывает запрос в /index\.php?product=gizmo&color=red&size=tiny&texture=furry&maker=gizmocorp, вызывая скрипт
  • Ваш скрипт генерирует запрошенную страницу, и сервер отсылает ее обратно браузеру клиента
  • Посетитель кликает на другую ссылку и процесс повторяется
Статья по теме:  Google отменил директиву rel=next и rel=prev для страниц пагинации

Теперь давайте посмотрим, как паук поисковика посетит ваш сайт, используя старый динамический URL:

  • Паук запрашивает с вашего сервера: //example.com/index\.php?product=wodget&color=green&size=large&texture=smooth&maker=wodgetsinc
  • Вызывается mod_rewrite и второе правило генерирует 301 редирект, информирующий паука, что запрошенная страница была перенесена на URL: //example.com/product/wodget/green/large/smooth/wodgetsinc
  • Паук отправляет запрос в свою базу адресов, чтобы изменить в ней старый динамический URL на новый, полученный из редиректа.
  • Паук вновь запрашивает страницу, которую он искал, но на этот раз, используя новый статический URL: //example.com/product/wodget/green/large/smooth/wodgetsinc
  • Вызывается mod_rewrite и первое правило переформировывает запрос в /index\.php?product=wodget&color=green&size=large&texture=smooth&maker=wodgetsinc, вызывая скрипт
  • Ваш скрипт сгенерирует запрошенную страницу, и сервер вернет ее обратно поисковому пауку для последующего парсинга и построения поискового индекса
  • Теперь паук будет обрабатывать страницы, содержащие новые статические ссылки и все запросы на старые динамические URL будут перенаправлены на новые статические URL, а новые URL в результатах поиска со временем заменят старые.

Размещение правил mod_rewrite

Чтобы приведенный код работал надлежащим образом, он должен быть размещен в файле .htaccess в том же каталоге, где и /index.php. Также он может быть помещен в контейнер <directory> в файле httpd.conf, который ссылается на этот каталог.

Регулярные выражения

Тут я приведу только одно замечание по поводу регулярных выражений, использованных выше. Я избегаю использования очень простых и популярных, но очень неэффективных конструкций «(.*)/(.*)«. Ибо использование множества конструкций «.*» в регулярных выражениях очень неэффективно.
Причины этому две. Первое — «.*» означает «подставить любое число любых символов». И второе — конструкция «.*» очень «прожорливая», что означает, что в шаблон подставится максимально возможное количество символов. А это в свою очередь означает, что, перед тем как запрошенный URL совпадет или не совпадет с регулярным выражением, произойдет множество подстановок, количество которых равно (количеству символов между «/» и концом запрашиваемого URL минус 2) умноженное на (количество «(.*)» минус один). Легко сделать регулярное выражение со множеством «(.*)», разбор которого потребует десятки или даже сотни проходов.
Давайте взглянем на короткий пример. Обратная связь $1 содержит символы, подставляемые в первую «(.*)«, а $2 — символы, подставляемые во вторую:
Запрошенный URL: //example.com/abc/def
Локальный путь: abc/def
Шаблон правила: ^(.*)/(.*)$

№ проходаЗначение $1Значение $2Результат
1abc/defне совпадает
2abc/defне совпадает
3abc/defне совпадает
4abc/defне совпадает
5abcdefсовпадает
Статья по теме:  Из чего складывается скорость загрузки сайта и как ее можно изменить

Я осмелюсь предположить, что множество сайтов проводят каждый год обновление серверов, но эту ошибку оставляют.

Вместо этой конструкции я использую «([^/]+)", "([^&]+)" и "([^\ ]+)«. В грубом переводе они соответственно означают «подставить один или несколько символов не равных слешу», «подставить один или несколько символов не равных &» и «подставить один или несколько символов не равных пробелу». Разница заключается в том, что каждая из этих конструкций будет «потреблять» один или более символов из запрошенного URL, увеличивая количество на один, тем самым, позволяя парсеру регулярных выражений проверить запрошенный URL за один проход слева-направо.

Частые проблемы

Самой частой проблемой, встречающейся при реализации преобразований URL из динамических в статические — это когда «бъются» относительные ссылки внутри вашей страницы (на изображения, на CSS файлы или внешние JavaScript).

Проблема в том, что браузер сам обрабатывает относительные ссылки. Например, если вы обрабатываете URL product/widget/blue/fuzzy/widgetco, то браузер увидит страницу «widgetco» и будет обрабатывать относительные ссылки этой страницы относительно «виртуального» каталога /product/widget/blue/fuzzy/.

Есть два простых решения этой проблемы. Первое — это использовать серверо-относительные ссылки (или абсолютные ссылки), или использовать дополнительные mod_rewrite правила для преобразования URL картинок, CSS файлов и т. п. Вот пример использования серверно-относительной ссылки <img src="/logo.gif">, которая заменяет странично-относительную ссылку <img src="logo.gif">.

Проблемы при тестировании

Как для .htaccess, так и для httpd.conf перед тестированием любых изменений не забывайте очищать кэш браузера. Иначе ваш браузер обработает одну из ранее запрошенных страниц из кэша. Понятно, что в этом случае, новый код не выполнится.

Оригинал на английском о том как преобразовать динамические ссылки в дружелюбные для поисковых систем: Changing dynamic to static URLs.


Понравилась статья? Поделиться с друзьями:
Комментарии: 64
  1. Руслан

    Почему у меня не меняется адрес страницы сайта непосредственно в адресной строке браузера?

    например:
    есть динамическая страница
    site.ru/viewcat.php?cat=auto

    я хочу что бы она отображалась как
    site.ru/auto.html

    в файле .htaccess прописано правило
    RewriteRule (.*)\.html$ viewcat.php?cat=$1

    Когда захожу на категорию авто, то всеравно в адресной строке отображается
    site.ru/viewcat.php?cat=auto

    Когда ввожу вручную в строку адреса
    site.ru/auto.html то удачно попадаю на категорию авто, то есть нет никаких ошибок

    Как все-таки сделать что-бы статические адреса отображались в строке адреса браузера?

  2. Tsamada

    Если я вас правильно понял, то вы хотите что бы ссылка «авто» выглядела так: auto.html

    Для этого вам нужно подправить ссылки в меню навигации. Если прописывается явно (вручную) <a href="/viewcat.php?cat=auto">авто</a>, то нужно viewcat.php?cat=auto просто заменить на auto.html ну и т. д. все пункты меню. Это первый вариант.

    Можно сделать и так: <a href ="/{$page}.html">{$title_menu}</a> — это при условии, что у вас формируемая ссылка имеет приблизительно такой вид: <a href="/viewcat.php?cat={$page}">{$title_menu}</a>.

    Но это все предположения. Более конкретный ответ можно дать если вы укажете как формируется ваша ссылка или если вы используете CMS, то какую.

  3. Руслан

    Нужно было подправить ссылки в меню навигации.

    Спасибо за подсказку!

    1. FORTRESS-DESIGN (автор)

      Я бы вам еще посоветовал делать ссылки не site.ru/auto.html, а site.ru/auto/ — не нужно показывать какие технологии использовались при разработке сайта. К тому же URL выглядит более чисто.

  4. Руслан

    Помогите мне написать регулярное выражение.

    Мне нужно находить в урл ссылки, где нету дефиса и цифр, то есть только буквенные символы

    1. Tsamada

      Пример:
      RewriteRule ^([A-Za-z]+)/$ ?lang=$1
      При переходе по site.ua/ru/ будем попадать на site.ua/?lang=ru

      Можно чуть подправить правило так:
      RewriteRule ^([A-Za-z]+)/?$ ?lang=$1
      При переходе по site.ua/ru/ и site.ua/ru будем попадать на site.ua/?lang=ru

      [A-Za-z] — означает все символы латиницы в обоих регистрах.

      ?$ — знак вопроса обозначает, что может быть или отсутствовать любой символ.

  5. jin

    Спасибо большое. Вот реально помогло «Частые проблемы». Казалось бы елементарное, а не знал, что слеш делает серверно-относительную ссылку и все ссылки летели.

  6. Андрей

    Здравствуйте, помогите пожалуйста с написанием директивы для .htaccess.
    Мне необходимо сделать переадресацию с единичной страницы http://www.site.ru/blog?id=135 на страницу http://www.site.ru/pogoda так как для странцы с текущей погоды я сделал новую страницу а в поисковиках сидит старая.
    Вот такая инструкция почему то не работает:

    Options +FollowSymLinks
    RewriteEngine On
    RewriteBase /
    RewriteCond %{QUERY_STRING} ^id=135
    RewriteRule ^blog(.*)$ http://www.site.ru/pogoda [L,R=301]

    как в прочем на работает и вариант с:
    Redirect permanent /blog?id=135 http://www.site.ru/pogoda
    как я понимаю во втором случае переадресации мешает знак вопроса.
    Заранее благодарен за помощь

  7. Андрей

    Спасибо, сам нашел решение.

    Options +FollowSymLinks
    RewriteEngine On
    RewriteBase /
    RewriteCond %{QUERY_STRING} ^id=135
    RewriteRule ^blog$ http://www.syzranlife.ru/pogoda-syzran? [L,R=301]
    
  8. Юрий

    Мой пример сходен с предыдущим, однако всё равно не получается. Нужно преобразовать Несколько конкретных ссылок. Пример http://www.site.ru/catalog/section1234/index.php?sub=3451 в http://www.site.ru/catalog/prodazha/

    Не помогает ничего — ни рерайт рул типа:
    RewriteRule ^article.jsp?id=(.*)$ /latestnews.htm [L,R=301]
    Ни RedirectMatch ни RedirectPermanent. Подскажите — где рыть?

  9. Юрий

    Ясно одно уже — дело может быть в адресе — потому что в корне сайта всё это работает с index.php

  10. Андрей

    Юрий попробуй так:

    Options +FollowSymLinks
    RewriteEngine On
    RewriteBase /
    RewriteCond %{QUERY_STRING} ^sub=3451
    RewriteRule ^catalog/section1234/index.php$ http://www.site.ru/catalog/prodazha/? [L,R=301]
    
  11. Виктор

    Спасибо, замучался уже. Не мог понять что делать с относительными ссылками

  12. Игорь

    Ничего не понял.

    Объясните мне как мне преобразовать вот такой URL
    mysite/index.php?razdel=led&topik=vse-pro-fonari
    на вот такой
    mysite/led/vse-pro-fonari.html

    1. Виктор

      mysite/led/vse-pro-fonari.html
      RewriteRule ^/(.*)/(.*).html?$ index.php?razdel=$1&topik=$2 [NC,L]

  13. Игорь

    У меня правило не заработало.

  14. Андрей

    Решил сайт на статичные url перевести, а ваша статья как раз пригодилась! Ну и про регулярки посмотрел ваши наработки, тоже пригодится.

  15. umvidocq

    Подскажете может быть, почему по отдельности такие конструкции:
    RewriteRule ^([A-Za-z]+)/$ page.php?c=$1
    и
    RewriteRule ^([A-Za-z]+)/$ view.php?v=$1
    работают, а когда они вместе:
    RewriteEngine on
    RewriteRule ^([A-Za-z]+)/$ view.php?v=$1
    RewriteRule ^([A-Za-z]+)/$ page.php?c=$1
    то не хотят. В чем загвоздка? Спасибо.

  16. Игорь

    По ходу ты один тот же урл пытаешься загнать на два адреса.
    Я думаю твой вариант теоретически нереализуем. Ищу другую структуру.

    1. umvidocq

      Да нет, уже сделал. Правда через urltrans.dat и при помощи напильника. Что-то подсказывает что можно в одну строчку все написать…

  17. Игорь

    Как реализовать такое правило:
    перенаправлять 301 рtдиректом ссылки вида
    site.com/zzfhdf/dfhdh
    на
    site.com/zzfhdf/dfhdh/
    но при этом не покушаться на
    site.com/zzfhdf/asfadgf.pdf
    site.com/zzfhdf/asfadgf.html
    и т.д.

    Человек забудет поставить кавычку и его выкинет на 404

  18. Татьяна

    помогите, уже несколько дней мучаюсь!
    пытаюсь преобразовать http://www.mysite.ru/stati.php?id=3
    в http://www.mysite.ru/stati/3/

    после ввода следующей инструкции выводится ошибка 500 на любую страницу сайта. В чем проблема?

    Options +FollowSymLinks
    RewriteEngine on
    
    RewriteRule ^id/([^/]+)/?$
    /stati.php?id=$1 [L]
    
    RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\
    /stati\.php\?id=([^/]+)\ HTTP/
    RewriteRule ^stati\.php$ http://mysite.ru/id/%1? [R=301,L]
    
  19. Константин
    RewriteCond %{QUERY_STRING} ^sub=3451
    RewriteRule ^catalog/section1234/index.php$ http://www.site.ru/catalog/prodazha/? [L,R=301]
    

    Это перенаправление с единичной страницы.
    Что нужно написать в .htaccess, чтобы происходило перенаправление со всех динамически созданных страниц, т.е.

    redirect from:
    catalog/section1234/index.php?sub=1
    ……
    catalog/section1234/index.php?sub=100500
    to
    http://www.site.ru/catalog/prodazha/1.html
    …….
    http://www.site.ru/catalog/prodazha/100500.html

    1. Константин

      Забавно, нашел решение сам

      RewriteCond %{QUERY_STRING} ^sub=([0-9]+)
      RewriteRule ^catalog/section1234/index.php$ http://www.site.ru/catalog/prodazha/%1.html? [L,R=301]
      

      Однако странная вещь, регулярки ([0-9]+) и (\d+) обозначают любое число. Но, работает только первый вариант.

      1. FORTRESS-DESIGN (автор)

        Я о втором варианте не знал. Видимо все же есть какая-то разница. Может устаревший формат записи?

  20. jobsdata

    Есть кто живой? :D

    Помогите преобразовать url.

    http://mysite.ru/search.php
    в
    http://mysite.ru/search/

    Спасибо (=

  21. Игорь

    Тебе надо везде отрезать php или только у одного этого файла?

    1. jobsdata

      у меня другие идут вот так
      RewriteRule ^page/$ /page.php?cat_id=1&cat_slug=spa [L]
      RewriteRule ^page/([0-9]*)$ /view.php?cat_id=1&item_id=$1&cat_slug=spa [L]
      тоесть из базы идут по id…а мне надо отдельный файл search.php , сделать в нормальном виде /search/ =)

  22. Барахолка ноутбуков

    На PHP можно сделать так что включается скрипт 404 который в свою очередь подменяет заголовки на 200 Ok и далее изучем что там в адресной строке либо целиком ее берем в базу либо частично /1/2 переменные туда загоняем без всяких мод реврайт =) гараздо удобней и понятней.

    1. Игорь

      С модреврайтом намного проще — не раздувайте просто так код — это неправильно.

      1. FORTRESS-DESIGN (автор)

        Буду признателен за пример в формате было — стало.

        1. Компьютерная барахолка

          В корне правим файл .htaccess или создаем новый обязательна строчка
          ErrorDocument 404 /index.php
          а далее в файле index.php

          Но есть и минусы сего не удается передать переменные в такой скрипт видимо когда срабатывает 404 данные теряются

          1. FORTRESS-DESIGN (автор)

            Че-то пропал кусочек кода…

  23. Игорь

    Какой пример? Я через php никогда ничего не делал.
    В модреврайте у меня на пять строк кода собственно. Это очень компактно.

    1. FORTRESS-DESIGN (автор)

      А где здесь говорится о преобразовании динамических URL в статические на PHP?

  24. Александр

    Добрый день!
    Как прописать такой редирект?
    http://bla-bla.com/category/televizor —> bla-bla.com/category/televizor/?pole

    ссылок порядка 80
    параметр ?pole не меняется

    спасибо

    1. Валерий

      Ага?
      RewriteRule ^/?category/(.*)/?$ http://bla-bla.com/category/$1\?pole [R=301,L]

  25. Татьяна

    Здравствуйте.
    Помогите, пожалуйста. Надо перенаправить со страницы вида http://na-krovatku.ru/index.php?route=product/category&path=20 на http://na-krovatku.ru/pastel'noe-bel'e как грамотно прописать. Нигде не могу найти.

    1. Валерий

      Проще простого :)
      RewriteEngine On
      RewriteCond %{QUERY_STRING} ^route=product/category&path=20$ [NC]
      RewriteRule ^index\.php$ http://na-krovatku.ru/pastel'noe-bel'e? [R=301,NE,NC,L]

      1. FORTRESS-DESIGN (автор)

        Спасибо.

        1. Валерий

          OpenCart страшная сила :)
          Пжалста.

      2. Татьяна

        Пишет, что циклическая переадресация.

        1. Валерий

          Найдите:
          # SEO URL Settings
          RewriteEngine On
          # If your opencart installation does not run on the main web folder make sure you folder it does run in ie. / becomes /shop/

          RewriteBase /
          RewriteRule sitemap.xml /index.php?route=feed/google_sitemap
          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

          Замените на:
          # SEO URL Settings
          RewriteEngine On
          # If your opencart installation does not run on the main web folder make sure you folder it does run in ie. / becomes /shop/

          RewriteCond %{QUERY_STRING} ^route=product/category&path=20$ [NC]
          RewriteRule ^index\.php$ http://na-krovatku.ru/pastel'noe-bel'e? [R=301,NE,NC,L]

          RewriteBase /
          RewriteRule sitemap.xml /index.php?route=feed/google_sitemap
          RewriteCond %{REQUEST_FILENAME} !-f
          RewriteCond %{REQUEST_FILENAME} !-d
          RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

          Проверил — работает.

          1. FORTRESS-DESIGN (автор)

            Большое спасибо.

  26. Татьяна

    Мой .htaccess. Перенаправления нет.(( Где может быть ошибка? Заранее спасибо за советы.
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^www.na-krovatku\.ru$ [NC]
    RewriteRule ^(.*)$ http://na-krovatku.ru/$1 [R=301,L]
    RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
    RewriteRule ^index\.php$ http://na-krovatku.ru/$1 [R=301,L]
    RewriteCond %{QUERY_STRING} ^route=product/category&path=20$ [NC]
    RewriteRule ^index\.php$ http://na-krovatku.ru/pastel'noe-bel'e? [R=301,NE,NC,L]

    RewriteBase /
    RewriteRule sitemap.xml /index.php?route=feed/google_sitemap
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

    1. Валерий

      RewriteEngine On
      RewriteCond %{HTTP_HOST} ^www.na-krovatku\.ru$ [NC]
      RewriteRule ^(.*)$ http://na-krovatku.ru/$1 [R=301,L]

      RewriteCond %{QUERY_STRING} ^route=product/category&path=20$
      RewriteRule ^index\.php$ /pastel'noe-bel'e? [R=301,L]

      RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index\.php\ HTTP/
      RewriteRule ^index\.php$ http://na-krovatku.ru/$1 [R=301,L]

      RewriteBase /
      RewriteRule sitemap.xml /index.php?route=feed/google_sitemap
      RewriteCond %{REQUEST_FILENAME} !-f
      RewriteCond %{REQUEST_FILENAME} !-d
      RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

  27. Татьяна

    Ну, помогите, пожалуйста. В первых двух случаях есть перенаправление (с www на без www), а вот уже с ЧПУ проблема…

    1. FORTRESS-DESIGN (автор)

      Татьяна, Валерий уже ушел домой, он сказал, что завтра вам поможет :).

      1. Татьяна

        Спасибо.))

        1. FORTRESS-DESIGN (автор)

          Это Валере спасибо :)

  28. Юлия

    Добрый день! Очень прошу вашей помощи. Я в этом деле чайник, все делаю методом тыка.

    Включила ЧПУ. Выбивало ошибку 500. Переписала файл .htaccess :

    #Options +FollowSymlinks

    # Prevent Directoy listing
    #Options -Indexes

    # Prevent Direct Access to files

    Order deny,allow
    Deny from all

    # SEO URL Settings
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

    # Additional Settings that may need to be enabled for some servers
    # Uncomment the commands by removing the # sign in front of it.
    # If you get an «Internal Server Error 500» after enabling any of the following settings, restore the # as this means your host doesn’t allow that.

    # 1. If your cart only allows you to add one item at a time, it is possible register_globals is on. This may work to disable it:
    # php_flag register_globals off

    # 2. If your cart has magic quotes enabled, This may work to disable it:
    # php_flag magic_quotes_gpc Off

    # 3. Set max upload file size. Most hosts will limit this and not allow it to be overridden but you can try
    # php_value upload_max_filesize 999M

    # 4. set max post size. uncomment this line if you have a lot of product options or are getting errors where forms are not saving all fields
    # php_value post_max_size 999M

    # 5. set max time script can take. uncomment this line if you have a lot of product options or are getting errors where forms are not saving all fields
    # php_value max_execution_time 200

    # 6. set max time for input to be recieved. Uncomment this line if you have a lot of product options or are getting errors where forms are not saving all fields
    # php_value max_input_time 200

    И переписала seo_url.php:

    request->get[‘_route_’])) {
    $parts = explode(‘/’, trim($this->request->get[‘_route_’], ‘/’));

    foreach ($parts as $part) {

    if( $this->config->get(‘config_seo_url_replace’) ) {
    $part = str_replace(‘_’, ‘ ‘, $part);
    }

    $query = $this->db->query(«SELECT * FROM » . DB_PREFIX . «url_alias WHERE keyword = ‘» . $this->db->escape($part) . «‘»);

    if ($query->num_rows) {
    $url = explode(‘=’, $query->row[‘query’]);

    switch ($url[0]) {
    case ‘product_id’:
    $this->request->get[‘product_id’] = $url[1];
    break;

    case ‘category_id’:
    if (!isset($this->request->get[‘path’])) {
    $this->request->get[‘path’] = $url[1];
    } else {
    $this->request->get[‘path’] .= ‘_’ . $url[1];
    }
    break;

    case ‘manufacturer_id’:
    case ‘information_id’:
    $this->request->get[$url[0]] = $url[1];
    break;

    default:
    break;
    }
    } else {
    $this->request->get[‘route’] = ‘error/not_found’;
    return $this->forward(‘error/not_found’);
    }
    }

    if (isset($this->request->get[‘product_id’])) {
    $reference = ‘index.php?route=product/product&product_id=’ . $this->request->get[‘product_id’];
    if ($this->checkUrl($reference) === false) {
    $this->request->get[‘route’] = ‘error/not_found’;
    } else {
    $this->request->get[‘route’] = ‘product/product’;
    }
    } elseif (isset($this->request->get[‘path’])) {
    $reference = ‘index.php?route=product/category&path=’ . $this->request->get[‘path’];
    if ($this->checkUrl($reference) === false) {
    $this->request->get[‘route’] = ‘error/not_found’;
    } else {
    $this->request->get[‘route’] = ‘product/category’;
    }
    } elseif (isset($this->request->get[‘manufacturer_id’])) {
    $this->request->get[‘route’] = ‘product/manufacturer’;
    } elseif (isset($this->request->get[‘information_id’])) {
    $this->request->get[‘route’] = ‘information/information’;
    }

    if (isset($this->request->get[‘route’])) {
    return $this->forward($this->request->get[‘route’]);
    }
    } elseif ($this->config->get(‘config_seo_url’) && isset($this->request->get[‘route’])) {
    if (isset($this->request->get[‘product_id’]) && $this->request->get[‘route’] == ‘product/product’) {
    $reference = ‘index.php?route=product/product&product_id=’ . $this->request->get[‘product_id’];
    } elseif (isset($this->request->get[‘path’]) && $this->request->get[‘route’] == ‘product/category’) {
    $reference = ‘index.php?route=product/category&path=’ . $this->request->get[‘path’];
    }

    if (isset($reference) && $this->checkUrl($reference) === false) {
    $this->request->get[‘route’] = ‘error/not_found’;
    return $this->forward(‘error/not_found’);
    }
    }
    }

    private function checkUrl($reference) {
    $this->load->model(‘tool/seo_url’);

    $seo_url = $this->model_tool_seo_url->rewrite(HTTP_SERVER . $reference, ‘validate’);

    if ($seo_url === false) return false;

    if (isset($this->request->get[‘_route_’])) {
    $url = HTTP_SERVER . $this->request->get[‘_route_’];
    } else {
    $url = HTTP_SERVER . ‘index.php?’ . urldecode(http_build_query($this->request->get));
    }

    if ($url != $seo_url) {
    header($this->request->server[‘SERVER_PROTOCOL’] . ‘ 301 Moved Permanently’);
    $this->redirect($seo_url);
    }

    return true;
    }
    }
    ?>

    Теперь вадает ошибку: Not Found

    The requested URL /http:ююю/index.php?route=product/category&path=20/ was not found on this server.

    Запуталась окончательно. Где искать ошибку, подскажите пожалуйста!

  29. Юлия

    Да, забыла написать, магазин на Opencart 1.5.4

  30. Сеттер

    Здравствуйте, очень нужна помощь, необходимо сделать редирект динамической ссылки такого вида —

    http://bd/reg.html?task=browse&view=search&sort=latest&start=10
    http://bd/reg.html?task=browse&view=search&sort=latest&start=
    http://bd/reg.html?task=browse&view=search&sort=latest&start

    Чтоб после слова start любые дописки переписывались и перенаправление было на http://bd/404.html

    Очень прошу помощи, очень важный момент, ответа нигде не нашел вы последняя моя надежда.
    Спасибо за внимание буду ждать вашего ответа.

  31. Сеттер

    Буду ждать так как ответа не могу найти, сам пробывал писать правило не получается

  32. Юлия

    А здесь никто не отвечает ) Мне так и не ответили…

    1. Валерий

      Ну почему же, я иногда отвечаю :)

      1. FORTRESS-DESIGN (автор)

        :)

  33. сеттер

    Вообщем если идеи будут пишите пожалуйста, пока вопрос заморозил резаньем функции view=search через мод реврайт

  34. Купоны

    Добрый день

    Помогите, пожалуйста, переадресовать динамический url карты сайта на новый адрес с помощью 301 редиректа.
    Эти 2 ссылки:
    http://kuponi.com.ua/index.php?option=com_xmap&sitemap=1
    http://kuponi.com.ua/index.php?option=com_xmap&sitemap=1&Itemid=151
    необходимо переадресовать на новую карту сайта
    http://kuponi.com.ua/sitemap.xml
    В интернете нашел такой код для динамических страниц:
    RewriteEngine On
    RewriteCond %{QUERY_STRING} ^option=com_xmap&sitemap=(.*)$
    RewriteRule .*$ http://kuponi.com.ua/sitemap.xml [L,R=301]

    но он работает неправильно, так как редиректит на ссылки

    http://kuponi.com.ua/sitemap.xml?option=com_xmap&sitemap=1

    и

    http://kuponi.com.ua/sitemap.xml?option=com_xmap&sitemap=1&Itemid=151

    вместо ссылки, как и писалось выше
    http://kuponi.com.ua/sitemap.xml

    Помогите найти правильное решение, пожалуйста

    Спасибо

  35. Купоны

    уже неактуально. спасибо

  36. Тамара

    Добрый день! Необходимо преобразовать http://www.site.ru/index.php?cat=1 в http://www.site.ru/cat/1. Пишу RewriteRule ^cat/1$ /index.php?cat=1 [L]. На локальном сервере (denwer) все работает. Переношу изменения на рабочий сервер — выдается ошибка 404. Что не так?

  37. Игорь

    Уважаемый Валерий, вы скольким людям здесь помогли, очень надеюсь, что вы ещё зайдете в эту тему хоть раз и поможете мне, сломавшему голову человеку :)

    Нужно это : http://epil24.ru/cart/add?category_id=20&product_id=207

    Перенаправить: идеально на 410 страницу.

  38. Олег

    Это реально самое полное и доходчивое руководство по преобразованию динамических URL в статические. Прям все что по крупицам собирал в сети — бац и нашел в одном месте. Спасибо!

  39. Александр

    Здравствуйте.
    Нужна помощь по данной теме:
    Как правильно в .htaccess прописать 301-й редирект с динамической страницы в url которой есть переменная ‘?’ на статическую страницу без этой переменной ‘?’
    http://site/?/ext/hhh/options.html нужно отредиректить на http://site/ext/hhh/options.html

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

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: