http> https неверный окончательный URL (перенаправление субдомена) - PullRequest
1 голос
/ 06 октября 2019

У меня есть:

дерево каталогов:

└───domains
    ├───bar.com
    │   ├───sub (sub.bar.com / www.sub.bar.com)
    │   ├───sub2 (sub2.bar.com / www.sub2.bar.com)
    │   └───www (bar.com / www.bar.com)
    └───foo.com
        ├───sub (sub.foo.com / www.sub.foo.com)
        ├───sub2 (sub2.foo.com / www.sub2.foo.com)
        └───www (foo.com / www.foo.com)
/.htaccess


RewriteEngine On

# remove www from URL
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,DPI,L,NC]

# subdomains (sub.foo.com, sub.bar.com, sub2.foo.com, sub2.bar.com)
RewriteCond %{REQUEST_URI} !^domains/
RewriteCond %{REQUEST_URI} !^/domains/
RewriteCond %{HTTP_HOST} ^([^\.]*)\.([^\.]*\.[^\.]*)$
RewriteCond %{DOCUMENT_ROOT}/domains/%2 -d
RewriteCond %{DOCUMENT_ROOT}/domains/%2/%1 -d
RewriteRule (.*) /domains/%2/%1/$1 [DPI]

# main domains (foo.com, bar.com)
RewriteCond %{REQUEST_URI} !^domains/
RewriteCond %{REQUEST_URI} !^/domains/
RewriteCond %{HTTP_HOST} ^([^\.]*\.[^\.]*)$
RewriteCond %{DOCUMENT_ROOT}/domains/%1 -d
RewriteRule (.*) /domains/%1/www/$1 [DPI]

Это выглядит, что работает довольно хорошо, но когда мне нужно включить https на foo.com, это не такработать как положено.

/domains/foo.com/.htaccess

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [DPI,R=301]

Потому что вместо перенаправления: http://www.sub.foo.com/?query> https://sub.foo.com/?query оно перенаправляет на: https://sub.foo.com/domains/foo.com/sub/?query, но это действительно не то, что я ожидаю.

1 Ответ

1 голос
/ 06 октября 2019

/domains/foo.com/.htaccess

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [DPI,R=301]

Это не работает должным образом при использовании в файле /domains/foo.com/.htaccess, поскольку он обрабатывается после URLбыл переписан файлом /.htaccess в корневом каталоге, и на этом этапе серверная переменная REQUEST_URI была обновлена ​​до полного URL-пути, на который был переписан запрос (не URL-адрес, запрошенный пользователем), т.е. ,/domains/foo.com/sub/.

( В сторону: Вы не указали, используете ли вы PHP, но уточнить на всякий случай ... REQUEST_URI суперглобальную переменную PHP, т.е.. $_SERVER['REQUEST_URI']), не совпадает с серверной переменной REQUEST_URI Apache. Переменная PHP REQUEST_URI содержит URL-адрес, запрошенный пользователем (который, вероятно, соответствует ожидаемой серверной переменной Apache), который в этом случае не совпадает с серверной переменной Apache с тем же именем.)

Простое решение - захватить URL-путь из URL-пути, соответствующего шаблону RewriteRule , вместо использования серверной переменной REQUEST_URI Apache.

Например:

# /domains/foo.com/.htaccess
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=301,L]

В .htaccess шаблон RewriteRule сопоставляется с URL-путем без префикса каталога - поэтому он всегда относительно каталога, содержащегофайл .htaccess.

Кажется, что флаг DPI здесь не требуется.

Альтернативное решение - переместить перенаправление HTTP на HTTPS в корневой файл /.htaccess ( до внутренняя перезапись) и, возможно, проверьте запрашиваемое имя хоста , если вам нужно быть избирательным. Например:

# /.htaccess
RewriteCond %{HTTPS} !=on
RewriteCond %{HTTP_HOST} ^(www\.)?sub\.foo\.com [NC]
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

В корневом файле /.htaccess мы можем использовать переменную Apache REQUEST_URI, при условии, что перенаправление помещено до внутреннего перезаписи.

Вам нужно очистить кеш браузера перед тестированием. Желательно тестировать с 302 (временными) перенаправлениями, чтобы избежать потенциальных проблем с кэшированием.


# remove www from URL
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,DPI,L,NC]

Еще одна «проблема» заключается в том, что перенаправление с www на не-www всегда перенаправляет на HTTP. Таким образом, запрос на https://www.sub.foo.com/ будет перенаправлен обратно в HTTP, прежде чем (мы надеемся) будет перенаправлен обратно в HTTPS - ненужное дополнительное перенаправление. Есть несколько способов решить эту проблему в зависимости от ваших требований.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...