Как я могу написать файл .htaccess для Apache, чтобы добавить PHP (если не указан) И использовать хорошо написанную страницу 404 - PullRequest
1 голос
/ 28 марта 2020

В Apache у меня есть рабочий файл .htaccess, который добавляет расширение. php к запрашиваемой странице веб-сайта, чтобы, например, https: // {{domain}} / sales -> обслуживать содержимое от https: // {{domain}} /sales.php, а для посетителя это выглядит как https: // {{domain}} / sales

Работает без нареканий.

Однако я не могу решить, как ТАКЖЕ использовать причудливую страницу 404. php с сервера.

Вот мое текущее содержимое файла .htaccess:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+)$ $1\.php [NC,L]

Свидетельство: если я выключу свой файл .htaccess (переименую его), страница 404 будет работать хорошо, основываясь на моих настройках httpd.conf , Итак, я почти уверен, что именно этот незрелый файл .htaccess мешает мне показывать причудливую страницу 404. Когда продажи не найдены. php страница не найдена.

Каковы точные строки в httpd.conf:

DocumentRoot "/var/www/html/"
ErrorDocument 404 "/404.php"

Кроме того, я попробовал каждый из: (и перезагрузил httpd после)

ErrorDocument 404 "/var/www/html/{{virtualHostDir}}/404.php"
ErrorDocument 404 "/404.php"
ErrorDocument 404 "404.php"

Я даже пытался добавить ErrorDocument напрямую в настройках virtualHost, но безрезультатно.


А что на самом деле происходит, когда вы получаете 404 и файл .htaccess на месте?

Я получаю страницу без html, это просто говорит: «Файл не найден».

1 Ответ

1 голос
/ 29 марта 2020
DocumentRoot "/var/www/html/"
ErrorDocument 404 "/404.php"

Это выглядит правильно. Если документ с ошибкой 404 находится в /var/www/html/404.php, то нет очевидной причины (из предоставленной информации), почему это не работает, как предполагалось. Он не является содержимым файла .htaccess - хотя вы можете попробовать альтернативный подход (см. Ниже).

Путь к директиве ErrorDocument должен быть документом - root -относительный URL-путь - начиная с sla sh. (Чтобы вызвать внутренний подзапрос к соответствующему документу об ошибке.)

Я даже пытался добавить ErrorDocument непосредственно в настройки virtualHost

Однако, если вы используете контейнеры VirtualHost, тогда эти настройки должны быть в соответствующих vHost (s). Все, что находится в vHost, переопределит конфигурацию основного сервера.

Очевидно, что если вы внесете какие-либо изменения в конфигурацию сервера / virtualhost, вам потребуется перезапустить Apache.

Поскольку вы в любом случае, используя .htaccess, вы также можете установить ErrorDocument в .htaccess - и это, в свою очередь, переопределит конфигурацию виртуального хоста / сервера.

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+)$ $1\.php [NC,L]

Ничего особенно плохого с этим ... вы соответствуете запрошенному URL-пути, который не содержит точку, и, если он еще не сопоставлен с файлом или каталогом, вы добавляете расширение .php.

Просто некоторые примечания относительно этого:

  • Вы добавляете расширение .php независимо от того, какой файл "с расширением .php" действительно существует. Это не обязательно неправильно, просто 404 запускается на /does-not-exist.php вместо /does-not-exist. Вместо этого вы можете проверить, существует ли файл назначения. Это позволит избежать необходимости проверять, что запрос еще не сопоставлен с файлом или каталогом.

  • Первое условие, которое проверяет, что запрос не сопоставляется с файлом, возможно, является ненужным, если только у вас есть файлы, которые не имеют расширений (очень маловероятно, я бы подумал).

  • [^\.] - нет необходимости backsla sh экранировать буквальную точку в регулярном выражении класс персонажей. (Хотя в этом нет никакого вреда, кроме читабельности ИМО.)

  • $1\.php - нет необходимости в обратном слэсе sh экранировать буквальную точку в RewriteRule замена . Этот аргумент является «обычной» строкой (не регулярное выражение), точка здесь не несет особого значения. (Хотя, опять-таки, в этом нет никакого вреда, кроме читабельности.)

  • Флаг NC на RewriteRule здесь не требуется, так как вы соответствуете everything за исключением точки в регулярном выражении, которая, естественно, в любом случае включает как прописные, так и строчные буквы.

  • Если это все, что вы используете для mod_rewrite, то вместо этого вы можете использовать MultiViews для обработки ваших расширений без расширений URL-адрес. Это то, что делает MultiViews (часть mod_negotiation). Учитывая запрос на /path/to/foo, если /path/to/foo.php существует, mod_negotiation будет обслуживать этот файл. Вам нужно будет удалить существующие директивы mod_rewrite (поскольку они будут эффективно конфликтовать и игнорироваться в любом случае), а затем включить MultiViews в верхней части вашего .htaccess файла:

    Options +MultiViews
    

В качестве альтернативы попробуйте следующее, принимая во внимание приведенные выше замечания:

RewriteEngine On

RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^.]+)$ $1.php [L]

Примечание: я предполагаю, что ваш файл .htaccess находится в документе root, ie. /var/www/html/.htaccess

...