htaccess заменяет полный URL вместо REQUEST_URI

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

  • non-www => www
  • non-https => https
  • /file.html => /utilities/template_handler.php?filename=file. html

Проблема: когда я запрашиваю https://example.com/file.html , я получаю от r = 301 до

https://example.com/utilities/template_handler.php? filename = https: //www.example.com/file.html

Мой .htaccess :

RewriteEngine On
RewriteBase /

RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301]

RewriteRule ^(.*)\.html$ /utilities/template_handler.php?filename=$1.html [NC]

Я использую веб-сервер litespeed, но для устранения неполадок также установил Apache, результат тот же. После включения отладки я вижу:

strip base: '/' from URI: '/file.html'
Rule: Match 'file.html' with pattern '.*', result: 1
Cond: Match 'on' with pattern 'off', result: -1
Rule: Match 'file.html' with pattern '.*', result: 1
Cond: Match 'domain.com' with pattern '^www\.', result: -1
Source URI: 'file.html' => Result URI: 'https://www.example.com/file.html'
Rule: Match 'https://www.example.com/file.html' with pattern '^(.*)\.html$', result: 2
Source URI: 'https://www.example.com/file.html' => Result URI: '/utilities/template_handler.php?filename=https://www.example.com/file.html'
replace current query string with 'filename=https://www.example.com/file.html'

Если я закомментирую последнее правило, первые два требования будут обработаны правильно.

Та же ошибка, если запрос отправлен на не-www или на www, но не-ssl.

2
задан 5 October 2017 в 22:17
1 ответ
  Скидка RewriteCond% {HTTPS}
RewriteRule. * Https: //% {HTTP_HOST}% {REQUEST_URI} [R = 301]
RewriteCond% {HTTP_HOST}! ^ Www \.  [NC]
RewriteRule. * Https: //www.% {HTTP_HOST}% {REQUEST_URI} [R = 301]
 

Вам необходимо включить флаг L ( last ) в обе эти директивы RewriteRule , в противном случае обработка файла будет продолжена, и URL-адрес будет далее переписывается следующим образом RewriteRule (с использованием вывода предыдущей директивы). А поскольку внешнее перенаправление уже было инициировано предыдущими директивами, вы получаете перенаправленное извне на /utilities/template_handler.php?filename = .... , а не ] внутренне переписан .

Эти директивы также должны быть отменены, чтобы избежать ненужного двойного перенаправления при запросе URL-адреса формы http: //example.com / ... . (В частности, с добавлением флага L .)

Например:

RewriteCond %{HTTP_HOST} !^www\.
RewriteRule .* https://www.%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

Обратите внимание, что я удалил флаг NC из инвертированного ! ^ www \. состояние. Поскольку это инвертированное регулярное выражение, вы хотите, чтобы оно перенаправляло, когда не запускается www - все в нижнем регистре. Вы по-прежнему хотите, чтобы перенаправлялись «плохие» запросы вида WwW , но если вы включите здесь флаг NC , они не будут.

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

2
ответ дан 3 December 2019 в 11:27

Теги

Похожие вопросы