Несколько правил = 1 редирект htaccess

Тема в разделе "Mod Rewrite / htaccess / ЧПУ", создана пользователем denik, 13 авг 2015.

  1. denik

    denik Постоялец

    Регистр.:
    1 июл 2011
    Сообщения:
    79
    Симпатии:
    43
    Пытаюсь преобразовывать URL несколько раз, чтоб в результате был 1 редирект, вместо нескольких подряд.

    Часть файла .htaccess:
    Код:
    RewriteEngine On
    
    # slash
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^.*[^/]$ $0/ [E=FINISH:1]
    
    # index
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^index/(.*)$ $1 [E=FINISH:1]
    
    # redirect
    RewriteCond %{ENV:FINISH} !^$
    RewriteRule ^(.*)$ /$0/ [E=!FINISH,R=301,L]
    Этот код должен преобразовать URL вида
    /index/segment1/segment2
    в
    /segment1/segment2/

    но вместо этого он делает:
    /segment1/segment2//segment1/segment2/segment1/segment2/

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

    Лог mod_rewrite по коду выше:
    [perdir /home/user/site.com/] add path info postfix: /home/user/site.com/index -> /home/user/site.com/index/segment1/segment2
    [perdir /home/user/site.com/] strip per-dir prefix: /home/user/site.com/index/segment1/segment2 -> index/segment1/segment2
    [perdir /home/user/site.com/] applying pattern '^.*[^/]$' to uri 'index/segment1/segment2'
    [perdir /home/user/site.com/] rewrite 'index/segment1/segment2' -> 'index/segment1/segment2/'
    [perdir /home/user/site.com/] add per-dir prefix: index/segment1/segment2/ -> /home/user/site.com/index/segment1/segment2/
    [perdir /home/user/site.com/] add path info postfix: /home/user/site.com/index/segment1/segment2/ -> /home/user/site.com/index/segment1/segment2//segment1/segment2
    [perdir /home/user/site.com/] strip per-dir prefix: /home/user/site.com/index/segment1/segment2//segment1/segment2 -> index/segment1/segment2//segment1/segment2
    [perdir /home/user/site.com/] applying pattern '^index/(.*)$' to uri 'index/segment1/segment2//segment1/segment2'
    [perdir /home/user/site.com/] rewrite 'index/segment1/segment2//segment1/segment2' -> 'segment1/segment2//segment1/segment2'
    [perdir /home/user/site.com/] add per-dir prefix: segment1/segment2//segment1/segment2 -> /home/user/site.com/segment1/segment2//segment1/segment2
    [perdir /home/user/site.com/] add path info postfix: /home/user/site.com/segment1/segment2//segment1/segment2 -> /home/user/site.com/segment1/segment2//segment1/segment2/segment1/segment2
    [perdir /home/user/site.com/] strip per-dir prefix: /home/user/site.com/segment1/segment2//segment1/segment2/segment1/segment2 -> segment1/segment2//segment1/segment2/segment1/segment2
    [perdir /home/user/site.com/] applying pattern '^(.*)$' to uri 'segment1/segment2//segment1/segment2/segment1/segment2'
    [perdir /home/user/site.com/] rewrite 'segment1/segment2//segment1/segment2/segment1/segment2' -> '/segment1/segment2//segment1/segment2/segment1/segment2/'
    [perdir /home/user/site.com/] explicitly forcing redirect with http://site.com/segment1/segment2//segment1/segment2/segment1/segment2/
    [perdir /home/user/site.com/] escaping http://site.com/segment1/segment2//segment1/segment2/segment1/segment2/ for redirect
    [perdir /home/user/site.com/] redirect to http://site.com/segment1/segment2//segment1/segment2/segment1/segment2/ [REDIRECT/301]

    Кто-то занимался такой фигней? Может у кого-то есть мысли, подсказки?
     
  2. Doctor_Chaos

    Doctor_Chaos Проктолог-гинеколог

    Moderator
    • Супермодератор
    Регистр.:
    7 сен 2013
    Сообщения:
    950
    Симпатии:
    645
    А если вот так:
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index/$1
     
  3. denik

    denik Постоялец

    Регистр.:
    1 июл 2011
    Сообщения:
    79
    Симпатии:
    43
    попробовал - тот же результат (
     
  4. denik

    denik Постоялец

    Регистр.:
    1 июл 2011
    Сообщения:
    79
    Симпатии:
    43
    Еще думал сделать так
    Код:
    # slash
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^.*[^/]$ $0/ [E=FINISH:1,R=301]
    Как читал в документации, R=301 - не должно прерывать чтение правил, а должно только запоминать какой редирект вызван.
    Вот только ничего подобного, после него сразу вызывается explicitly forcing redirect.
    Может надо еще какой флаг вызывать, чтоб редирект происходил только по нахождению L или достижению конца документа?
     
  5. lag

    lag

    Регистр.:
    13 окт 2014
    Сообщения:
    194
    Симпатии:
    235
    Составить шаблон под /index/segment1/segment2 можно так
    Код:
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^index/(.*[^/])$ /$1/ [R=301,L]
    
    или так
    Код:
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(?:index/)?(.*[^/])$ /$1/ [R=301,L]
    
     
    Последнее редактирование: 13 авг 2015
  6. denik

    denik Постоялец

    Регистр.:
    1 июл 2011
    Сообщения:
    79
    Симпатии:
    43
    это понятно, тут уже скорее спортивный интерес.
    разобраться почему именно не срабатывает очередность правил...
     
  7. denik

    denik Постоялец

    Регистр.:
    1 июл 2011
    Сообщения:
    79
    Симпатии:
    43
    Если кому пригодится, решение:
    Код:
    # slash
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^.*[^/]$ $0/ [E=FINISH:1,DPI]
    
    # index
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^index/(.*)$ $1 [E=FINISH:1,DPI]
    
    # redirect
    RewriteCond %{ENV:FINISH} !^$
    RewriteRule ^.*$ /$0 [E=!FINISH,DPI,R=301,L]
    The DPI flag causes the PATH_INFO portion of the rewritten URI to be discarded.

    This flag is available in version 2.2.12 and later.

    In per-directory context, the URI each RewriteRule compares against is the concatenation of the current values of the URI and PATH_INFO.

    The current URI can be the initial URI as requested by the client, the result of a previous round of mod_rewrite processing, or the result of a prior rule in the current round of mod_rewrite processing.

    In contrast, the PATH_INFO that is appended to the URI before each rule reflects only the value of PATH_INFO before this round of mod_rewrite processing. As a consequence, if large portions of the URI are matched and copied into a substitution in multiple RewriteRule directives, without regard for which parts of the URI came from the current PATH_INFO, the final URI may have multiple copies of PATH_INFO appended to it.

    Use this flag on any substitution where the PATH_INFO that resulted from the previous mapping of this request to the filesystem is not of interest. This flag permanently forgets the PATH_INFO established before this round of mod_rewrite processing began. PATH_INFO will not be recalculated until the current round of mod_rewrite processing completes. Subsequent rules during this round of processing will see only the direct result of substitutions, without any PATH_INFO appended.
     
  8. Zacker2

    Zacker2

    Регистр.:
    19 фев 2013
    Сообщения:
    218
    Симпатии:
    54
    Поясните пожалуйста вот такую тему, всеми известный rutor с 1 мая заблокирован всеми российскими провайдерами, относительного этого события появилось соответствующее сообщение на сайте:

    Но, при вводе основного домен, происходит редирект минуя сообщение о блокировке моего провайдера, и я все равно вижу нужную страницу, только уже на новом домене (зеркале). Появляется вопрос, как админам удалось сделать такой редирект, ведь провайдер блокирует домен, а не ip или сам сервер...