Не работает перенаправление URL-адреса, ориентированное на SEO

#php #apache #.htaccess

#php #apache #.htaccess

Вопрос:

На моем тестовом сервере с Apache и php7.1 я могу работать с подобным URL example.com/news/id/title -адресом, и он перенаправляет меня example.com/news.php , но URL-адрес остается тем же, и я могу использовать параметры после косых черт.

Теперь я работаю на живом хостинге, и он больше не работает. Я попытался перенаправить с помощью htaccess, и это работает для example.com/news перенаправления example.com/news.php , но если я добавлю что-нибудь после этого, я получу ошибку 404.

Как я могу перенаправить запросы /news/id/ туда news.php , где я хочу прочитать идентификатор? И почему это работало изначально на моем тестовом сервере?

Тысяча благодарностей за любую подсказку.

Мой фактический .htaccess :

 RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^news/(.*) /news.php/$1 [R=301,NC,L]
  

Комментарии:

1. Можете ли вы поделиться более подробной информацией?

2. Обратите внимание, почему этот вопрос был закрыт? Все подробности есть в вопросе, если у вас есть опыт работы с MultiViews и .htaccess .

3. Я тоже этого не знаю. Я сделал все улучшения в потоке. @MrWhite большое спасибо за вашу помощь и время!

Ответ №1:

Похоже, у вас может возникнуть конфликт с MultiViews (часть mod_negotiation). Вам нужно убедиться, что функция MultiViews отключена в верхней части вашего .htaccess файла:

 Options -MultiViews
  

Если включена функция MultiViews и вы делаете запрос на /news/id/ , то mod_negotiation выполняет внутренний подзапрос на /news.php (без какой-либо дополнительной информации о пути), прежде чем mod_rewrite сможет переписать запрос.

почему это работало изначально на моем тестовом сервере?

По умолчанию в Apache функция MultiViews отключена, однако ряд общих веб-хостингов по какой-то причине ее включают. Это заставляет URL-адреса без расширения «волшебным образом» работать, ничего не делая, однако это потенциально создает дублирующий контент (плохо для SEO) и вызывает бесконечные неожиданные конфликты с mod_rewrite, такие как этот.

ОБНОВЛЕНИЕ: вместо этого измените свои директивы на что-то вроде следующего:

 RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^news/(.*) /news.php/$1 [L]
  

Это внутренне переписывает (в отличие от _externally redirects_) all requests that start /news//news.php//news.php to - where is passed as _path-info_ to `. (Я предполагаю, что передача URL-пути в качестве path-info является намерением? Вы могли бы вместо этого использовать строку запроса или ничего не передавать в директиве и просто проверить запрошенный URL-адрес в PHP? — но это может потребовать немного большей обработки в PHP.)

Нет необходимости проверять, существует ли целевой файл, поскольку в этом примере он жестко запрограммирован.

Удаление R флага приводит к внутренней перезаписи.

Вам нужно будет очистить кэш вашего браузера, поскольку 301 (постоянное) перенаправление будет кэшировано браузером.

Если вам нужно более общее решение, которое переписывает /<action>/<data> /<action>.php/<data> , напишите его следующим образом:

 RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^/] )/(.*) /$1.php/$1 [L]
  

Опять же, нет необходимости проверять, что запрос не сопоставляется с файлом, прежде чем проверять, что он сопоставляется с файлом при .php добавлении.

Обратите внимание, что при этом не используется тестовая строка формы %{REQUEST_FILENAME}.php (как у вас было изначально), поскольку это может привести к циклу перезаписи (ошибка 500) для определенных запросов. Смотрите мой ответ на следующий вопрос о ServerFault, который объясняет это подробнее: https://serverfault.com/questions/989333/using-apache-rewrite-rules-in-htaccess-to-remove-html-causing-a-500-error

Комментарии:

1. Большое спасибо. Похоже, что это точка на моем тестовом сервере. Но как я могу перенаправить все запросы с example.com/news/id/title на example.com/news.php?=id на моем реальном сервере? Я нашел решение для перенаправления всех запросов на index.php но я хочу работать с разными php-файлами.

2. Я упустил из виду, что вы перенаправляли запрос извне . Похоже, вместо этого вам следует внутренне переписать запрос. Я обновил свой ответ.

3. действительно MultiViews , иногда может быть очень раздражающим

4. @CodeTube Как вы справились с этим? Если это ответило на ваш вопрос, пожалуйста, отметьте его как «принятый», нажав галочку / галочку рядом с ответом (чтобы помочь другим читателям и удалить вопрос из очереди неотвеченных вопросов). После того, как у вас будет 15 повторений, вы также можете проголосовать за ответы, которые сочтете полезными. Спасибо, очень признателен. 🙂