Моя ситуация такова: у меня есть статические файлы в папке public/
на моем локальном сервере. Любой входящий запрос должен быть перенаправлен в эту папку, но если к файлу в этой папке осуществляется прямой доступ, он должен быть либо 404, либо перенаправлен на «slug». Пример:
Request: /my-file
Should rewrite to: /public/my-file.html
URL should be: http://localhost/my-file
Request: /public/my-file.html
Should rewrite to: /public/my-file.html
URL should be: http://localhost/my-file
У меня есть следующие правила и условия в моем .htaccess
:
RewriteCond %{DOCUMENT_ROOT}/public/%{REQUEST_URI}.html -f
RewriteRule ^.*$ /public/$0.html [L,C]
RewriteCond %{REQUEST_URI} ^/public
RewriteRule ^public/(.+).html$ /$1 [R=301,L]
Сверху донизу:
/public/{request}.html
файл?/public/{request}.html
, и цепочку к (3), чтобы предотвратить цикл перенаправления/public
?public/{request}.html
: /{request}
. Также сделайте 301
заголовок, который сообщает моему браузеру и поисковым роботам, что страница переместилась навсегда. Запрос снова пройдет по всем правиламИтак, если мы выполним эти два запроса:
1. Request: /my-file
/public/my-file.html
оценивается как истина; файл существует в моей папке./public/my-file.html
, цепочка до 3Все идет нормально; отображается нужный файл с нужным мне URL. Запрос номер 2, который представляет собой запрос фактического файла в том виде, в каком он существует в файловой структуре:
2. Request: /public/my-file.html
public/public/my-file.html.html
принимает значение false, файл не существует в моей папке./public
public/my-file.html
к /my-file
, и идти сверху.Теперь, после (4) во 2-м примере, я бы сказал, что запрос соответствует 1-му примеру, что означает, что я получаю страницу, которую ищу, с правильным URL-адресом (из-за 301). Но это не работает: URL-адрес не меняется, я получаю страницу, которую ищу, но не URL-адрес (который должен быть /my-file
).
У кого-нибудь есть указатели? Я думаю, что почти готов, но что-то не так с цепочкой или перенаправлением. Спасибо!
Перепробовав всевозможные вещи, я наконец решил, что то, что я хочу, вероятно, невозможно. Я хочу перенаправить существующий файл (public/my-file.html
) в несуществующий файл (my-file
) визуально, но внутри я хочу, чтобы он запрашивал существующий путь к файлу. Это неизбежно приведет к циклу перенаправления, потому что mod_rewrite просто так не работает:
User typed: website.com/my-file
Rewrites to file path: .../wwwroot/public/my-file.html
Internal redirect
Rewriterule found: /public/my-file.html should redirect to my-file
See above.
Я не встречал подобной ситуации здесь, на ServerFault или StackOverflow - обычно переписывание идет на общий .php
файл, а не существующий .html
файл.
Я отметил ответ Криста ван Бесиена как правильный, поскольку он указал мне правильное направление для понимания всего этого.
В следующем вопросе проблема была решена с помощью %{THE_REQUEST}
: Посмотреть здесь
Вы можете просто проверить наличие реальных файлов / папок и пропустить ...
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
Вы можете иметь несколько Cond перед правилом.
То, что это не работает должным образом, связано с порядком выполнения RewriteConds и RewriteRules. RewriteRules оцениваются перед RewriteConds, которые им предшествуют. Итак, закажите ваш запрос на /public/my-file.html
обрабатывается так: (Я сохраню вашу нумерацию)
.*
в конце концов соответствует чему угодно ..RewriteConds (а у вас может быть несколько) принадлежат RewriteRule, которое следует за ними, и оцениваются только в том случае, если сначала совпадает шаблон в RewriteCond. Я знаю, это немного нелогично.
О синтаксисе читайте здесь: Перенаправление, изменение URL-адресов или перенаправление HTTP на HTTPS в Apache - все, что вы когда-либо хотели знать о правилах Mod_Rewrite, но боялись спросить
Как решить вашу проблему?
Может что-то вроде:
RewriteRule ^/public/(.*)$ /$1 [R=301,L]
RewriteRule ^(-*)$ /public/$1
И последний совет: включите журнал перезаписи. Выучите связку ...