Это сводит меня с ума.
Предыстория: я использую встроенные Apache2 и PHP, которые поставляются с Mac OS X 10.6.
У меня следующая настройка vhost:
NameVirtualHost *:81
<Directory "/Users/neezer/Sites/">
Options Indexes MultiViews
AllowOverride None
Order allow,deny
Allow from all
</Directory>
<VirtualHost *:81>
ServerName lobster.dev
ServerAlias *.lobster.dev
DocumentRoot /Users/neezer/Sites/lobster/www
RewriteEngine On
RewriteCond $1 !^(index\.php|resources|robots\.txt)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]
LogLevel debug
ErrorLog /private/var/log/apache2/lobster_error
</VirtualHost>
Это в /private/etc/apache2/users/neezer.conf
.
Мой код в lobster project
это PHP с Фреймворк CodeIgniter. Пытаюсь загрузить http://lobster.dev:81/ дает мне:
ошибка 400, неверный запрос
Обычно я проверял свои журналы, чтобы узнать, что вызвало это, но мои журналы пусты! Я посмотрел в оба /private/var/log/apache2/error_log
и /private/var/log/apache2/lobster_error
, и ни один из них не записывает ЛЮБОЕ сообщение, относящееся к 400. У меня LogLevel
установлен в debug
в /private/etc/apache2/http.conf
.
Удаление правил перезаписи избавляет от ошибки, но эти же правила работают на моем хосте MAMP. Я перепроверил и rewrite_module
загружается в мою установку Apache по умолчанию. Мой http.conf
можно найти здесь: https://gist.github.com/1057091
Что дает? Дайте мне знать, если вам понадобится дополнительная информация.
ПРИМЕЧАНИЕ. Я НЕ хочу добавлять правила перезаписи в .htaccess
в каталоге проекта (он зарегистрирован в репозитории git, и я не хочу его трогать).
Для сложных правил mod_rewrite рекомендуется регистрировать последовательность событий, чтобы увидеть, что происходит. Сделайте это, используя RewriteLog, и провернуть RewriteLogLevel чтобы увидеть подробности.
mod_rewrite очень гибкий, и с помощью правил перезаписи можно многое делать, а также он довольно сложен. Постороннему будет трудно отладить ваши правила, не видя более широкого контекста. Лучшее, что вы можете сделать, отладить самостоятельно. Следите за журналами в одном окне, пока вы экспериментируете с изменениями конфигурации во втором окне. Внесите небольшое изменение, сохраните файл, перезагрузите apache и снова нажмите URL-адрес. Повторение.
Вот хорошее описание RewriteLog от Apache руководство:
Переписать журнал
При использовании мощных и сложных функций mod_rewrite почти всегда необходимо использовать RewriteLog для помощи в отладке. Этот файл журнала производит подробный анализ того, как механизм перезаписи преобразует запросы. Уровень детализации контролируется директивой RewriteLogLevel.
Ваша замена в <virtualhost>
context использует неабсолютный URL. Вы не можете сделать это вне контекста Directory / htaccess.
Еще несколько примечаний, которые стали слишком большими, чтобы их можно было поместить в простой комментарий:
RewriteCond $1
работает, но довольно опасно и хрупко. В частности, вы могли бы легко переписать RewriteRule, чтобы полностью отключить функциональность этого RewriteCond, и вы бы никогда не узнали об этом. Использование %{REQUEST_URI}
рекомендуется как решение, à la RewriteCond %{REQUEST_URI} ^/(index\.php|resources|robots\.txt)
.
Следующая проблема: эти две строчки:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
не функциональны, как представлено. Их либо нужно разместить внутри <Directory>
строфы или модифицированы для использования макросов упреждающего просмотра (например, RewriteCond %{LA-U:REQUEST_FILENAME} !-f
).
Фактическая причина, по которой вам нужно удалить /
в том, что .htaccess
снимает ведущую /
из первого аргумента RewriteRule, тогда как он доставляется с /
без изменений в RewriteRules в httpd.conf (или его Include
d), что важно запомнить, если вы когда-нибудь попытаетесь переместить это правило обратно в .htaccess. Вы можете изменить правило, сделав его независимым от .htaccess / httpd.conf, выполнив что-то вроде RewriteRule ^/?(.*)$ index.php/$1 [L,QSA]
.
И последнее замечание: как вы можете видеть в правиле выше, вам не нужно избегать /
с обратной косой чертой.