простой 301 редирект с переменной не работает, почему? - PullRequest
1 голос
/ 18 октября 2011

Вот что я получил до сих пор.Первая часть работает, но не сам редирект.

Что мне нужно сделать, чтобы это работало?

RewriteEngine On
RewriteRule ^([^/\.]+)/?$ page.php?name=$1 [L]

RewriteRule ^page.php?name=([^/\.]+)/?$ /$1  [R=301,L] 

Кроме того, если у меня есть несколько из этих правил, я оставляю [L] только на последнем?

1 Ответ

1 голос
/ 19 октября 2011

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

RewriteEngine On
RewriteBase /

RewriteCond %{QUERY_STRING} ^name=([^/.&]+)/?$
RewriteCond %{ENV:REDIRECT_LOOP} !1
RewriteRule ^page\.php$ /%1?  [NS,R=301,L]

RewriteRule ^([^/.]+)/?$ page.php?name=$1 [NS,QSA,E=LOOP:1]

(я включил флаг QSA, чтобы URL типа /foobar?foo=bar был переписан на /page.php?name=foobar&foo=bar вместо просто /page.php?name=foobar. Если вы этого не хотите, оставьте его .)


Примечание: Второе RewriteCond предназначено для предотвращения повторного сопоставления первого правила после сопоставления второго. Проблема заключается в том, что в контексте .htaccess mod_rewrite действует более или менее так, как если бы все правила имели флаг PT, вызывая повторный запуск набора правил с начала после каждой перезаписи. даже внутренние. Или , чтобы процитировать документацию :

"Если вы используете RewriteRule в файлах .htaccess или в разделах , важно иметь некоторое представление о том, как обрабатываются правила. Упрощенная форма этого состоит в том, что после обработки правил переписанный запрос передается механизму синтаксического анализа URL, чтобы сделать с ним все возможное. Возможно, что при обработке переписанного запроса файл .htaccess или раздел могут быть обнаружены снова, и, таким образом, может быть запущен набор правил. снова с самого начала. Чаще всего это происходит, если одно из правил вызывает перенаправление - либо внутреннее, либо внешнее - и процесс запроса запускается заново. "

Обходной путь, который я использую, - установить пользовательскую переменную среды с E=LOOP:1, когда внутренняя перезапись срабатывает, и проверить ее перед выполнением внешней перезаписи. Обратите внимание, что, когда обработка запроса возобновляется после внутренней перезаписи, Apache добавляет REDIRECT_ к именам всех переменных среды, установленных во время предыдущего прохода, поэтому даже если переменная, которую мы установили, называется просто LOOP, нам нужно чек на это REDIRECT_LOOP.

...