Неправильные URL-адреса в wp-admin на WordPress с подкаталогом и прокси.

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

Я использую apache2 и mod-proxy для интеграции блогов WordPress в поддиректории моего TLD.

Виртуальный хост Apache2 для основного сайта с прокси:

<VirtualHost *:80>
ServerName example.com

...

# Правило перенаправления для добавления отсутствующих слэшей
RewriteRule ^/blog$ /blog/ [R=301]
RewriteRule ^/other-blog$ /other-blog/ [R=301]

<Proxy *>
Order deny,allow
Allow from all
</Proxy>

ProxyRequests off
ProxyPass /blog/ http://blog1.localhost/
ProxyPassReverse /blog/ http://blog1.localhost/
ProxyPass /other-blog/ http://blog2.localhost/
ProxyPassReverse /other-blog/ http://blog2.localhost/

...

</VirtualHost>

Виртуальные хосты Apache2 для блогов:

<VirtualHost *:80>
ServerName blog1.localhost
DocumentRoot /var/www/blog1/
<Directory />
Options FollowSymLinks
AllowOverride All
</Directory>
</VirtualHost>

Добавление строк в файл hosts Linux:

127.0.0.1     blog1.localhost localhost.localdomain
127.0.0.1     blog2.localhost localhost.localdomain

WordPress: Настройки > Общие настройки:

Файл .htaccess:

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

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

или

Что я пробовал сделать:

Ничего из этого не помогло или даже ухудшило ситуацию.

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

*) Редактирование: Что я уже пробовал здесь:

define('WP_HOME',  'http://' . $_SERVER['HTTP_HOST'] . '/blog');
define('WP_HOME', 'http://example.com/blog');
define('WP_SITEURL', 'http://example.com' . $_SERVER['SERVER_NAME'] . '/blog');
define('WP_SITEURL', 'http://' . $_SERVER['SERVER_NAME'] . '/blog');
define('WP_SITEURL', 'http://example.com/blog/');

Абсолютные (и неправильные) пути содержатся в контенте, сгенерированном WordPress — невозможно их переписать с помощью Apache (как Apache узнает, о каком блоге идет речь, когда клиент запрашивает /wp-content?).

Изменение URL сайта в конфигурации WordPress – правильный путь.

Для экземпляра блог1:

define('WP_SITEURL', 'http://example.com/blog');

Для экземпляра блог2:

define('WP_SITEURL', 'http://example.com/other-blog');

Что вы пробовали, и какое поведение наблюдали?

На февраль 2025 года WordPress не полностью готов к запуску в подкаталоге “из коробки”.

Первым шагом обязательно должна быть настройка URL сайта и URL домашней страницы в wp-config.php, включая подкаталог, в котором расположены файлы WordPress:

const WP_SITEURL = 'https://example.com/subfolder';
const WP_HOME = WP_SITEURL;

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

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

К счастью, исправить это обычно довольно просто. В следующем примере показаны необходимые исправления для wp-login.php:

diff --git a/wp-login.php b/wp-login.php
index 16faccb70..b193f6a26 100644
--- a/wp-login.php
+++ b/wp-login.php
@@ -831,7 +831,7 @@ switch ( $action ) {
						$errors = retrieve_password();
 
						if ( ! is_wp_error( $errors ) ) {
-							   $redirect_to = ! empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : 'wp-login.php?checkemail=confirm';
+							   $redirect_to = ! empty( $_REQUEST['redirect_to'] ) ? $_REQUEST['redirect_to'] : site_url( 'wp-login.php?checkemail=confirm', 'login' );
								wp_safe_redirect( $redirect_to );
								exit;
						}
@@ -930,13 +930,14 @@ switch ( $action ) {
		case 'resetpass':
		case 'rp':
				list( $rp_path ) = explode( '?', wp_unslash( $_SERVER['REQUEST_URI'] ) );
+				$rp_path		 = site_url( $rp_path );
				$rp_cookie="wp-resetpass-" . COOKIEHASH;
 
				if ( isset( $_GET['key'] ) && isset( $_GET['login'] ) ) {
						$value = sprintf( '%s:%s', wp_unslash( $_GET['login'] ), wp_unslash( $_GET['key'] ) );
						setcookie( $rp_cookie, $value, 0, $rp_path, COOKIE_DOMAIN, is_ssl(), true );
 
-					   wp_safe_redirect( remove_query_arg( array( 'key', 'login' ) ) );
+					   wp_safe_redirect( site_url( remove_query_arg( array( 'key', 'login' ) ), 'login' ) );
						exit;
				}
 

По сути, вам нужно найти места, где генерируется ссылка или URL для перенаправления без учета URL сайта, и обернуть их в site_url( ..., 'login'), например:

-'wp-login.php?checkemail=confirm'
+site_url( 'wp-login.php?checkemail=confirm', 'login' )

-remove_query_arg( array( 'key', 'login' ) )
+site_url( remove_query_arg( array( 'key', 'login' ) ), 'login' )

(Второй аргумент 'login' применяется только в случае изменений в wp-login.php и обычно его нужно опустить в других местах.)

Я отправлю патчи для ядра WordPress, WooCommerce и Elementor в ближайшие дни.

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

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

.

Ответ или решение

Конфигурация WordPress с использованием подкаталогов и прокси на базе Apache может быть сложной задачей, особенно когда возникают проблемы с неправильными URL-адресами в админке (wp-admin) и контенте (wp-content). Давайте подробно разберем возможные решения этой проблемы в контексте WordPress, размещенного в подкаталогах через Apache2 и mod_proxy.

Теория

Когда вы используете подкаталоги для размещения различных экземпляров WordPress через прокси-сервер Apache, вы по существу обеспечиваете маршрутизацию запросов через ваш основной домен (например, example.com) к локальным адресам (например, blog1.localhost, blog2.localhost). Каждый из этих подкаталогов должен правильно обрабатывать и модифицировать структуру URL, чтобы WordPress мог правильно интерпретировать и обрабатывать запросы.

Основная проблема, с которой вы столкнулись, связана с тем, что без дополнительных настроек WordPress пытается генерировать URL с корнем вашего основного домена (например, /wp-admin/ вместо /blog/wp-admin/), что приводит к неправильным маршрутам и ошибкам загрузки контента.

Пример

Рассмотрим вашу текущую установку. Вы настроили виртуальные хосты Apache таким образом, чтобы main site и два блоговых сайта были доступны через подкаталоги:

<VirtualHost *:80>
ServerName example.com

RewriteRule ^/blog$ /blog/ [R=301]
RewriteRule ^/other-blog$ /other-blog/ [R=301]

<Proxy *>
Order deny,allow
Allow from all
</Proxy>

ProxyRequests off
ProxyPass /blog/ http://blog1.localhost/
ProxyPassReverse /blog/ http://blog1.localhost/
ProxyPass /other-blog/ http://blog2.localhost/
ProxyPassReverse /other-blog/ http://blog2.localhost/

</VirtualHost>

Базовая конфигурация предполагает перенаправление запросов из корневого домена в нужные подкаталоги. Однако, важной частью является правильная настройка WordPress URL.

Применение

  1. Настройка wp-config.php: Убедитесь, что вы правильно указали переменные WP_SITEURL и WP_HOME в файле wp-config.php для каждого экземпляра WordPress. Это ключевой шаг, поскольку эти параметры определяют, как WordPress будет воспринимать базовый адрес сайта.

    Для первого блога:

    define('WP_SITEURL', 'http://example.com/blog');
    define('WP_HOME', 'http://example.com/blog');

    Для второго блога:

    define('WP_SITEURL', 'http://example.com/other-blog');
    define('WP_HOME', 'http://example.com/other-blog');
  2. Исправление кода WordPress: WordPress и сторонние плагины не всегда готовы работать в подкаталогах без дополнительных исправлений в коде. Рассмотрите возможность корректировки кода, особенно если вы видите, что URL-адреса генерируются неправильно. Например, проверьте файлы вроде wp-login.php и подобные, чтобы убедиться, что URL-адреса всегда включают в себя ваш подкаталог:

    Пример исправления в wp-login.php:

    - wp_safe_redirect( remove_query_arg( array( 'key', 'login' ) ) );
    + wp_safe_redirect( site_url( remove_query_arg( array( 'key', 'login' ) ), 'login' ) );
  3. Переписывание правил .htaccess: Убедитесь, что ваш файл .htaccess настроен правильно для каждого блога. Например, для первого блога:

    <IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /blog/
    RewriteRule ^index\.php$ - [L]
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /blog/index.php [L]
    </IfModule>
  4. Проверка базы данных: Иногда проблема может заключаться в сохраненных настройках URL в базе данных. Проверьте таблицы, такие как wp_options, на наличие неправильных URL и исправьте их вручную, если это необходимо.

  5. Тестирование и отладка: После внесения изменений убедитесь, что протестированы все разделы сайта на наличие остаточных ошибок в ссылках или проблем с загрузкой. Используйте инструменты разработчика в вашем браузере для отладки сетевых запросов и посмотрите, какие URL вызываются неправильно.

  6. Обновление и исправление кода: Если изменения в конфигурации и коде не помогают, возможно, стоит составить перечень участков кода, вызывающих проблемы, и предложить исправления или патчи команде WordPress, если такие репортировать невозможно.

Заключение

Развертывание WordPress в подкаталогах при помощи прокси-сервера может требовать значительных усилий, особенно из-за необходимости вносить изменения и исправления не только в конфигурационные файлы, но и в сам исходный код WordPress и его плагинов. Тем не менее, соблюдение надлежащей конфигурации, отладка и внимательное отношение к разветвленной настройке системы помогут вам достичь желаемого результата. Если вы сталкиваетесь с проблемами, которые не можете решить самостоятельно, рассмотрите возможность обращения за помощью к сообществу WordPress или к профессиональным консультантам.

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

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