у меня есть .htaccess
файл :
RewriteEngine On
DirectorySlash Off
RewriteCond %{REQUEST_URI} !(\.css|\.js|\.png|\.jpg|\.mp4|\.ttf|\.eot|\.woff)$
RewriteRule ^(.*)$ ?page=$1 [NC,L,QSA]
ErrorDocument 404 /e404
ErrorDocument 403 /e404
ErrorDocument 500 /e500
И функция PHP, которая проверяет, существует ли запрошенный URI. Если URI существует в базе данных, он получит содержимое и отобразит страницу, если нет, он получит содержимое страницы с ошибкой 404 и отобразит страницу. (Здесь все ОК)
Проблема в том, что я использую URI с расширениями, которые находятся внутри RewriteCond
часть .htaccess
файл, что-то вроде example.com/file.css
. В этом случае страница перенаправляется на example.com/e404
(это то, что я хочу). Проблема здесь в следующем:
Я не знаю, как получить "неправильный URI" перед перенаправлением на example.com/e404
, потому что, когда страница с ошибкой загружается, у меня есть функция внутри страницы для вставки «неправильного URI» в базу данных.
В стороне: Опубликованные вами директивы создадут цикл перезаписи при любой установке Apache по умолчанию, поэтому, возможно, у вас есть другие директивы или другая конфигурация, которую вы не раскрываете в своем вопросе? Во всяком случае, игнорируя это на данный момент, поскольку у вас, похоже, нет такой проблемы.
Я не знаю, как использовать неправильный URI перед перенаправлением на
example.com/e404
...
Но нужна ли вам эта информация перед "перенаправление"? В PHP вы можете просто проверить $_SERVER['REQUEST_URI']
superglobal для получения этой информации (URL-адрес, который привел к ошибке 404). Однако обратите внимание, что он содержит префикс косой черты и строку запроса (если есть), которую вы page
В противном случае параметр URL не содержал бы.
Кроме того, чтобы уточнить терминологию, это не строго "перенаправление" на example.com/e404
. «Перенаправление» подразумевает внешнее перенаправление HTTP. Apache выдает внутренний подзапрос для документа об ошибке (который похож на перезапись URL, но не совсем).
Одна из потенциальных проблем с вашим кодом заключается в том, что ответ 404 обслуживается довольно круговым способом:
file.css
не существует, то Apache запускает внутренний подзапрос для /e404
/e404
не оканчивается одним из указанных расширений файла, в дальнейшем он переписывается на ?page=e404
(предположительно index.php
?).Из-за (ненужной) второй перезаписи другие переменные сервера, такие как REDIRECT_URL
и REDIRECT_QUERY_STRING
(которые также передаются в PHP $_SERVER
superglobal) установлены не так, как ожидалось. Обычно для них устанавливается «неправильный URI» (т. Е. Запрошенный URL-адрес, который вызвал 404), но вместо этого они содержат подробную информацию о самом документе об ошибке.
Вы должны сделать это за 1 шаг и избежать повторной перезаписи. Например (при условии index.php
файл, обрабатывающий запрос), в документе об ошибке должен быть указан желаемый конечный результат:
ErrorDocument 404 /index.php?page=e404
Между прочим, вам не обязательно явно передавать «статус ошибки» HTTP (т.е. e404
) в URL-адресе, так как это доступно в PHP $_SERVER['REDIRECT_STATUS']
суперглобальный.
RewriteRule ^(.*)$ ?page=$1 [NC,L,QSA]
Я предполагал, что вы переписываете на index.php
(зарегистрированный DirectoryIndex)? Вместо того, чтобы позволить mod_dir выдать дополнительный подзапрос для DirectoryIndex, вы должны быть явным и включить файл, который вы перезаписываете, в замена. Например:
RewriteRule ^(.*)$ index.php?page=$1 [QSA,L]
(The NC
флаг здесь лишний.)
Я не знаю, как использовать неправильный URI перед перенаправлением на
example.com/e404
...
Вернувшись назад, чтобы снова обратиться к вашему первоначальному запросу (как академические упражнения). Вы можете сделать это на Apache 2.4.13+ (хотя я не думаю, что вы необходимость к). В Apache 2.4.13+ вы можете создать динамический ErrorDocument, используя выражения Apache.
Например, чтобы явно передать URL-путь, вызвавший ошибку 404 в URL-адресе самого документа с ошибкой, вы можете сделать что-то вроде следующего:
ErrorDocument 404 /index.php?page=%{escape:%{REQUEST_URI}}&error=404
Параметр URL page
затем содержит URL-путь (который включает префикс косой черты, в отличие от вашей перезаписи, которая исключает его). Вдобавок error
Параметр URL отправляет статус HTTP (хотя, как упоминалось выше, это не обязательно).