Nano Hash - криптовалюты, майнинг, программирование

mod_rewrite псевдоним подкаталога

Я как всегда борюсь с mod_rewrite. У нас есть несколько клиентских порталов, работающих через мультисайт WordPress, доступ к которым осуществляется через подкаталог: portal.

Например: http://www.mydomain.com/portal/clientA/

Я хотел бы иметь возможность попасть туда, просто набрав http://www.mydomain.com/clientA/, и это перенаправит меня на http://www.mydomain.com/portal/clientA/

Вот что у меня есть до сих пор, и я не могу ничего переписать:

RewriteCond %{REQUEST_URI} /portal/
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule . - [S=1]

RewriteRule /clientA(/?) /portal/clientA/

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

Вторую часть я не могу трогать, потому что она нужна WordPress. Мой шаблон также пытается предвидеть, что кто-то не поставит косую черту в конце, поэтому (/?)

EDIT: я также должен отметить, что я не хочу создавать более общее правило - мне удобно добавлять правило перезаписи для каждого нового клиента и каждый раз увеличивать число S=x.

РЕДАКТИРОВАТЬ (11 августа). Итак, немного повозившись, это то, что находится в моем .htaccess:

RewriteEngine On
RewriteRule ^clientA(/?) /portal/clientA/ [R]

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress

Излишне говорить, что это не работает. Однако первая часть работает, если я удалю весь раздел WordPress. Мне нужно, чтобы они ОБА работали одновременно. ЧТО такого в части WordPress, которая вызывает сбой первого раздела? Я предполагаю, что это комбинация RewriteBase и самого последнего правила, которое сравнивает все остальное с /index.php, что, честно говоря, немного обломно. На самом деле я не совсем понимаю, как это правило может работать даже в многосайтовом контексте, и тем не менее, похоже, что оно работает.

ОКОНЧАТЕЛЬНОЕ РЕШЕНИЕ спасибо LazyOne за правильный ответ! Для справки других, окончательное решение, которое я использовал, было:

RewriteEngine On
RewriteRule ^clientA(/.+)? /portal/clientA$1 [R,L]
RewriteRule ^clientB(/.+)? /portal/clientB$1 [R,L]


# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

# END WordPress
21.07.2011

Ответы:


1

Вот так просто:

RewriteCond %{REQUEST_URI} !^/portal/
RewriteRule (.*) /portal/$1 [L]

Он перепишет (внутреннее перенаправление) все запросы в папку /portal/ (например, /clientA/something => /portal/clientA/something).

Если вам нужно сделать это только для некоторых клиентов (или, лучше сказать, только для определенных папок, которые являются клиентами, но при этом иметь некоторые общие/общие папки как есть), вы можете использовать это правило для каждого клиента:

RewriteRule ^clientA(.*) /portal/clientA$1 [L]

Так что .htaccess будет выглядеть так:

RewriteRule ^clientA(.*) /portal/clientA$1 [L]
RewriteRule ^clientB(.*) /portal/clientB$1 [L]

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
21.07.2011
  • Спасибо за это предложение. Единственная проблема заключается в том, что с директивой [L]ast перезаписи WordPress не произойдет, и они должны произойти (даже для клиентских папок), чтобы включить красивые постоянные ссылки в WP. 11.08.2011
  • @ Том Почему этого не произойдет? Увидев, что переписывание флага [L] переходит к следующей итерации (именно так это работает — L не означает прекратить переписывание и немедленно уйти) .. и все равно достигнет правил перезаписи WordPress. Но да, вы можете немного ускорить его, удалив флаг L. Остальное зависит от WordPress, сможет ли он обработать ссылку /portal/clientA/something. О флаге [L]: stackoverflow.com/questions/6797998/ . Если у вас есть свои правила перезаписи в конфигурации сервера, то флаг [L] лучше вообще не использовать. 11.08.2011
  • Ах! Спасибо за разъяснение [Л]. Я думал, что он сразу после этого перестал обрабатывать .htaccess. Теперь, если вы посмотрите на мой обновленный пост, вы увидите, что он все еще работает неправильно. Это из-за RewriteBase? 11.08.2011
  • @Tom Что не работает, какой URL? Как это должно работать (согласно созданным вами правилам)? 11.08.2011
  • Спасибо за помощь. Итак, ввод «mydomain.com/clientA» дает мне страницу с ошибкой mydomain.com/portal/404. ОДНАКО, я должен быть честным и сказать, что я не реализовал ваше решение по захвату остальной части URL-адреса и добавлению его обратно, поэтому я попробую это и сообщу. 11.08.2011
  • Хорошо, я попробовал ваше решение дословно, и у меня все еще есть ошибка 404. Ах! Великолепно, вы должны добавить [R], чтобы это сработало! И я думаю, вам нужно [L], чтобы предотвратить перезапись WordPress во время этого цикла. Спасибо за вашу помощь! 11.08.2011
  • @LazyOne, у меня также есть вопрос о перенаправлении URL, похожий на этот, опубликуйте в wordpress.stackexchange http://wordpress.stackexchange.com/questions/68078/why-my-htacess-rewrite-return-404, вы можете мне помочь? спасибо 13.10.2012
  • @fishman У вас есть настоящая папка с именем def (или любое другое настоящее имя)? Возможно, у вас есть какие-то другие правила перезаписи (в файле .htaccess в этой папке), которые не позволяют вам переписывать дальше. Нынешние правила мне кажутся приемлемыми. 13.10.2012
  • Я знаю, что это не одобряется, но проблема с этим решением заключается в том, что при использовании команды [R] (перенаправление) вы теряете базовый путь в URL-адресе. Для некоторых это может быть хорошо и модно, но я нашел способ обойти это, обновив строку 147 в wp-includes/class-wp.php. Я изменил строку на эту: $req_uri = preg_replace(@'/^\/?p\/([-a-zA-Z0-9_]+)\//', '', $_SERVER['REQUEST_URI']); Где мой шаблон перезаписи подкаталога — /p/anyword/(take_to_root). Надеюсь, это поможет кому-то! Было больно найти способ сделать это. 22.11.2012

  • 2

    Я разместил часть этого в качестве комментария, но подумал, что людям, которые приземляются здесь, может быть более понятно сделать это в качестве ответа. Что касается ОП, он нашел способ сделать это с помощью строки [R] (перенаправление), но это устраняет созданную вами структуру URL-адреса подкаталога, которая была бы предпочтительнее в большинстве перезаписей URL-адресов. Итак, ранее опубликованный ответ верен, я не оспариваю это, но в зависимости от вашей реализации вы все равно можете получать ошибки WordPress 404. Вот решение моей ситуации, которое, я думаю, может быть более распространенным.

    В моем случае мне нужна была такая структура URL:

    http://mysite.com/p/profile_name/
    

    Каждый пользователь, который приходит зарегистрироваться, может создать свой собственный профиль на лету, и, за исключением нескольких модификаций контента, по большей части будет отображаться весь контент WordPress в корне. По сути, мне нужно это:

    http://mysite.com/p/profile_name/(.*)
    

    Чтобы быть переписанным к этому:

    http://mysite.com/$1
    

    Это код .htaccess, опубликованный в другом ответе, который БУДЕТ правильно обрабатывать это правило:

    RewriteRule ^p/([-a-zA-Z0-9_]+)(/.*) $2 [L]
    

    Проблема в том, что WordPress не заботится о вашей перезаписи с точки зрения понимания того, что такое $2, потому что WordPress использует $_SERVER['REQUEST_URI'], и независимо от того, что вы переписываете, это всегда то, что находится в окне браузера пользователя. ОП нашел способ обойти это, используя опцию [R], но это приводит к тому, что вы теряете свой URL:

    RewriteRule ^p/([-a-zA-Z0-9_]+)(/.*) $2 [R,L]
    

    Перенаправления:

    http://mysite.com/p/profile/(.*)
    

    To:

    http://mysite.com/$1
    

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

    Я придумал решение; однако это связано с взломом включаемых файлов WordPress :( Если у кого-то есть лучший способ, обновите его. Итак, начнем:

    РЕШЕНИЕ

    Я установил свой файл .htaccess равным этому:

    # BEGIN WordPress
    <IfModule mod_rewrite.c>
    RewriteEngine On
    #My addition:
    RewriteRule ^p/([-a-zA-Z0-9_]+)(/.*) $2 [L]
    
    RewriteBase /
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
    </IfModule>
    # END WordPress
    

    Затем я узнал, что WordPress использует переменную REQUEST_URI, поэтому я выполнил рекурсивный поиск и нашел эту строку кода в /wp-includes/class-wp.php (строка 147 v3.4.2):

    $req_uri = $_SERVER['REQUEST_URI'];
    

    Я изменил это на это:

    $req_uri = preg_replace(@'/^\/?p\/([-a-zA-Z0-9_]+)\//', '', $_SERVER['REQUEST_URI']);
    

    Что в основном просто обманывает WordPress, отфильтровывая содержимое профиля в начале URI.

    Наконец, мне также нужно было решение для ссылок на сайте. Для этого я добавил этот фильтр:

    ПРИМЕЧАНИЕ. Некоторые из этих регулярных выражений могут быть немного сумасшедшими; Я отфильтровывал специфические материалы сайта, поэтому, пожалуйста, используйте это как концепцию, а не как копирование/вставку.

    function mysite_wp_make_link_relative( $link ) {
        $sBaseUrl = (preg_match('/^\/(p\/[-a-zA-Z0-9_]+\/)(.*)/', $_SERVER['REQUEST_URI'], $matches)) ? $matches[1] : '';
        return preg_replace( '|https?://[^/]+/(.*)|i', '/' . $sBaseUrl . '$1', $link );
    }
    function rw_relative_urls() {
        $filters = array(
            'page_link', // Page link
            'home_url',
            'site_url',
            'get_site_url',
            'home_link',
        );
        foreach ( $filters as $filter ) {
            add_filter( $filter, 'mysite_wp_make_link_relative' );
        }
    }
    

    Некоторые из этих фильтров могут не иметь значения; Я почти уверен, что page_link и home_url являются единственными важными. В любом случае, вам нужен этот код для работы вашей внутренней ссылки.

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

    21.11.2012
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..