Неполные RewriteRules в Apache - PullRequest
       30

Неполные RewriteRules в Apache

1 голос
/ 19 февраля 2012

У меня следующие правила в .htaccess

Options +FollowSymlinks
RewriteEngine on
DirectoryIndex index.php
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]
RewriteRule ^captcha/(.*)$ captcha/captcha.php?cid=$1 [QSA,L]
RewriteRule ^index\.(html|php)$ / [R=301,L]
RewriteCond %{REQUEST_URI} !^/(index\.php|robots\.txt|favicon\.ico|(css|images|js|captcha)/)
RewriteRule ^(.*)$ ?get=$1 [QSA]

Это должно сделать внутреннее следующее (без изменения URL пользователя в браузере)

/something => /index.php?get=something
/?abc=def => /index.php?abc=def
/something?some=var => /index.php?get=something&some=var

технически это делает то, что я хочу. Но это должно сделать переписать без изменения URL пользователя в браузере (он должен только перенаправить внутренний). Но для первого и третьего примера браузер пользователя перенаправляется следующим образом

/something => /something/?get=something
/something?some=var => /something/?get=something&some=var

Но это не то, что я хочу (URL не должен манипулироваться - это должно быть внутреннее переписывание). Кто-нибудь может помочь?

1 Ответ

1 голос
/ 19 февраля 2012

Это печально известная проблема с косой чертой.

На самом деле ваш вышеприведенный .htaccess будет работать нормально, если к URL-адресу обращаются с косой чертой в конце.то есть yourdomain/something/, но он не будет работать для yourdomain/something

Почему?

Без завершающего слеша Apache будет рассматривать его как файл и искать его.Не найдя его.Он попытается исправить себя, добавив косую черту в конце.

К этому времени RewriteCond %{REQUEST_URI} !^/(index\.php|rob... уже будет удовлетворен, а RewriteRule ^(.*)$ ?get=$1 [QSA] уже будет обработан один раз.и URL уже будет иметь ?get=something.

Теперь, после того как Apache добавляет завершающий слеш и обрабатывает .htaccess, это не внутреннее перенаправление (200).поэтому

RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]

потерпит неудачу.И RewriteCond %{REQUEST_URI} !^/(index\.php|rob... удовлетворит, и RewriteRule ^(.*)$ ?get=$1 [QSA] будет обработан снова.

А также apache установит URL для временного перенаправления вскоре после добавления завершающего слеша.На данный момент ваш URL выглядит как yourdomian.com/something/?get=something. Вот почему URI отражается в браузере.то есть

/something => /something/?get=something
/something?some=var => /something/?get=something&some=var

, но ваш index.php действительно будет видеть:

/something => ?get=something/&get=something
/something?some=var => ?get=something/&get=something&some=var

Соль:

RewriteEngine on
RewriteBase /
DirectoryIndex index.php

#add these 2 lines
RewriteCond %{ENV:REDIRECT_STATUS} 200
RewriteRule ^ - [L]

#add these
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_URI} !\.\w+$
RewriteCond %{REQUEST_URI} !/$ 
RewriteRule (.*) /$1/ [R,L]

RewriteRule ^captcha/(.*)$ captcha/captcha.php?cid=$1 [QSA,L]

RewriteRule ^index\.(html|php)$ / [R=301,L]

RewriteCond %{REQUEST_URI} !^/(index\.php|robots\.txt|favicon\.ico|(css|images|js|captcha)/) [NC]
RewriteRule ^(.*)$ ?get=$1/ [L,QSA]
  • Проверяет, существует ли файл.

    RewriteCond %{REQUEST_URI} !-f [OR]

  • Проверяет, что запрос URI не имеет расширения в конце

    RewriteCond %{REQUEST_URI} !\.\w+$

  • Проверяет, есть ли в конце косая черта.

    RewriteCond %{REQUEST_URI} !/$

  • Если вышеуказанное удовлетворяет, перенаправьте текущий URL с косой чертой.

    RewriteRule (.*) /$1/ [R,L]
    R (перенаправление) по умолчанию имеет 302 (временное перенаправление).

...