.htaccess - Перенаправить в родительский каталог, если файл не существует - PullRequest
0 голосов
/ 06 мая 2019

У меня есть версия amp для некоторых страниц на моем сайте, но для некоторых - только обычная версия.В целом структура выглядит следующим образом:

\
\page1.htm
\page2.htm
...
\amp\
\amp\page1.htm

Итак, page1.htm имеет свою версию усилителя, а page2.htm - нет.Когда пользователь получает \amp\page2.htm вместо 404, я хотел бы подать page2.htm из корневого каталога.

Я пытался выполнить перенаправление через .htaccess, но он работает неправильно:

RewriteCond %{REQUEST_URI} ^/amp/
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteRule ^/amp/(.*)$ https://www.example.com/$1 [R=301,L]

Что не так с этим кодом?Почему я все еще получаю 404?

Спасибо!

1 Ответ

1 голос
/ 06 мая 2019

Это сложный вопрос, который подчеркивает тонкости mod_rewrite. Короткий ответ: есть два способа сделать это:

RewriteCond %{REQUEST_URI} ^/amp/(.*)$
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . https://www.example.com/%1 [R=301,L]

Несколько важных отличий:

  1. Я фиксирую завершающую часть REQUEST_URI в RewriteCond, а не в RewriteRule, а затем ссылаюсь на него, используя PERCENT 1 (%1), а не DOLLAR 1 ($1)
  2. Я использую REQUEST_FILENAME, чтобы увидеть, существует ли файл в файловой системе, а не DOCUMENT_ROOT / REQUEST_URI, потому что REQUEST_URI может быть чем угодно и может совпадать или не совпадать с тем, что находится в файловой системе (как показывает ваш пример).
  3. RewriteRule соответствует всему (., а не /amp/)

Или вы можете сделать:

RewriteBase /amp
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^amp(.*)$ $1 [R=301,L]

Почему эти два различных подхода работают вокруг этой цитаты из официальной документации mod_rewrite (выделено мной):

Обратите внимание, что mod_rewrite пытается угадать, указали ли вы путь файловой системы или URL-путь , проверив, существует ли первый сегмент пути в корне. файловой системы. Например, если вы укажете строку подстановки в /www/file.html, то это будет рассматриваться как URL-путь, если каталог с именем www не существует в корне или вашей файловой системе (или, в случае использования перезаписей в файле .htaccess относительно корня вашего документа), в этом случае он будет рассматриваться как путь к файловой системе.

Первый подход рассматривает вещи как URL-путь, тогда как второй подход рассматривает вещи как путь к файлу.

Я собираюсь предположить, что первый подход больше соответствует тому, что вам понадобится, поскольку решения amp часто «генерируются» (и не живут как плоские файлы в файловой системе), и, таким образом, вы больше заинтересованы в работе с вводом как URL-путь, чем как путь к файлу.

И прежде чем подумать: «Ух ты! Как люди могут держать это в своих мозгах?». У меня есть только смутное понимание правил mod_rewrite, и мне пришлось перечитать документацию и выполнить ряд тестов, чтобы прояснить для себя все перед тем, как писать это.

Надеюсь, это поможет.

Некоторые URL для справки:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...