Я работаю над чем-то, что должно быть действительно простым, но на второй день биться головой об стену. Требования к перенаправлению URL-адресов:
/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.
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]
Вам нужно включить 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
если хотите - хотя это было бы хорошей практикой. Фактически это подразумевается, так как в любом случае это последнее правило, но если вы добавили больше директив, вам, возможно, придется не забыть добавить его.