Еще более короткая версия моего файла .htaccess (последнего RewriteCond там не было) отлично работает на моем общем веб-хостинге, но я перешел на VPS с Ubuntu 12 со стандартным Apache2, но он просто не будет работать (даже с моими изменениями), и я не могу понять почему. Я могу получить доступ к example.com или example.com/news, но не к example.com/article/4
Я поместил блок mod_rewrite из .htaccess в конфигурацию vhost наоборот, но это, похоже, не сработало. Я предполагаю, что он на самом деле пытается перейти в подкаталог статьи или что-то в этом роде (которого не существует, так что 404), но я не могу понять, как остановить его от этого.
Я использую Apache версии 2.2.22
Мой файл виртуального хоста
<VirtualHost 127.0.0.1:80>
DocumentRoot /home/example/www/example.com
RewriteLogLevel 3
RewriteLog /home/example/www/example.rewrite.log
<Directory "/home/example/www/example.com">
AllowOverride All
Options -ExecCGI +FollowSymLinks -Indexes -MultiViews
Order deny,allow
allow from all
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteOptions inherit
</IfModule>
</Directory>
AccessFileName .htaccess
ServerSignature Off
ServerName example.com
ErrorLog /home/example/www/example.log
LogLevel warn
</VirtualHost>
Мой файл .htaccess
ErrorDocument 404 /index.php?404
ErrorDocument 403 /index.php?403
ErrorDocument 500 /index.php?500
Options -ExecCGI +FollowSymLinks -Indexes -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteOptions inherit
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-s
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteRule ^(.*)$ /index.php?$1 [L]
</IfModule>
Переписать журнал цикла перенаправления при доступе к example.com/article/4
[example.com/sid#8475130][rid#867d470/initial] (3) [perdir /home/example/www/example.com/] add path info postfix: /home/example/www/example.com/article -> /home/example/www/example.com/article/4
[example.com/sid#8475130][rid#867d470/initial] (3) [perdir /home/example/www/example.com/] strip per-dir prefix: /home/example/www/example.com/article/4 -> article/4
[example.com/sid#8475130][rid#867d470/initial] (3) [perdir /home/example/www/example.com/] applying pattern '^(.*)$' to uri 'article/4'
[example.com/sid#8475130][rid#867d470/initial] (2) [perdir /home/example/www/example.com/] rewrite 'article/4' -> '/index.php?article/4'
[example.com/sid#8475130][rid#867d470/initial] (3) split uri=/index.php?article/4 -> uri=/index.php, args=article/4
[example.com/sid#8475130][rid#867d470/initial] (2) [perdir /home/example/www/example.com/] trying to replace prefix /home/example/www/example.com/ with /
[example.com/sid#8475130][rid#867d470/initial] (1) [perdir /home/example/www/example.com/] internal redirect with /index.php [INTERNAL REDIRECT]
[example.com/sid#8475130][rid#b6ce9950/initial/redir#1] (3) [perdir /home/example/www/example.com/] strip per-dir prefix: /home/example/www/example.com/index.php -> index.php
[example.com/sid#8475130][rid#b6ce9950/initial/redir#1] (3) [perdir /home/example/www/example.com/] applying pattern '^(.*)$' to uri 'index.php'
[example.com/sid#8475130][rid#b6ce9950/initial/redir#1] (1) [perdir /home/example/www/example.com/] pass through /home/example/www/example.com/index.php
[example.com/sid#8475130][rid#b6cd7058/initial] (3) [perdir /home/example/www/example.com/] strip per-dir prefix: /home/example/www/example.com/404 -> 404
[example.com/sid#8475130][rid#b6cd7058/initial] (3) [perdir /home/example/www/example.com/] applying pattern '^(.*)$' to uri '404'
[example.com/sid#8475130][rid#b6cd7058/initial] (2) [perdir /home/example/www/example.com/] rewrite '404' -> '/index.php?404'
[example.com/sid#8475130][rid#b6cd7058/initial] (3) split uri=/index.php?404 -> uri=/index.php, args=404
[example.com/sid#8475130][rid#b6cd7058/initial] (2) [perdir /home/example/www/example.com/] trying to replace prefix /home/example/www/example.com/ with /
[example.com/sid#8475130][rid#b6cd7058/initial] (1) [perdir /home/example/www/example.com/] internal redirect with /index.php [INTERNAL REDIRECT]
[example.com/sid#8475130][rid#b6ce5440/initial/redir#1] (3) [perdir /home/example/www/example.com/] strip per-dir prefix: /home/example/www/example.com/index.php -> index.php
[example.com/sid#8475130][rid#b6ce5440/initial/redir#1] (3) [perdir /home/example/www/example.com/] applying pattern '^(.*)$' to uri 'index.php'
[example.com/sid#8475130][rid#b6ce5440/initial/redir#1] (1) [perdir /home/example/www/example.com/] pass through /home/example/www/example.com/index.php
Обобщенный журнал доступа
"GET /article/4 HTTP/1.1" 302 4095 "-"
"GET /404 HTTP/1.1" 200 2405 "-"
Журналы показывают, что ваши правила работают идеально.
В index.php
скрипт был выполнен с аргументами ?article/4
и сценарий ответил перенаправлением 302 на /404
. Здесь нет [R]
в любом из этих правил перезаписи, поэтому перенаправление должен быть выполнен скриптом.
Браузер сделал дополнительный запрос для /404
и было получено 200 ответов.
Подозреваю, у вас три проблемы. Во-первых, ваш скрипт выдает ответ 302 на URL-адрес. /404
когда он не может найти контент. Это должен выдать ответ 404.
Во-вторых, ваш /404
сценарий выдает ответ 200. Это должен выдать ответ 404.
В-третьих, ваш скрипт index.php не знает, как обращаться с аргументом ?article/4
. Я не знаю, как работает ваш скрипт, но я бы посоветовал немного отладить сам скрипт, чтобы решить вашу проблему. Использовать echo()
на некоторых переменных на разных этапах сценария или что-то вроде file_put_contents("/var/log/apache2/example.com.debug.log", time()." ".$variable."\n", FILE_APPEND)
.
Ваши исходные правила перезаписи кажутся достаточно простыми:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteOptions inherit
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-s
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/index\.php
RewriteRule ^(.*)$ /index.php?$1 [L]
</IfModule>
Вы пробовали использовать простой SEO / SEF .htaccess
например, тот, который идет в комплекте с WordPress? Вот он, но я добавил RewriteOptions inherit
правило из исходной настройки:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteOptions inherit
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>