Как я могу создать перенаправление с .htaccess для правильного пути вместо доступа к странице

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

Итак, французские страницы идут по адресу domain.com/fr/ english domain.com/en/page domain.com/fr/some/page, но на самом деле эти страницы находятся в базовой папке, а /fr/ преобразуется в строку запроса.

Все это работает со следующим .htaccess:

RewriteEngine on
DirectorySlash Off # Fixes the issue where a page and folder can have the same name. See https://stackoverflow.com/questions/2017748

# Return 404 if original request is /foo/bar.php
RewriteCond %{THE_REQUEST} "^[^ ]* .*?\.php[? ].*$"
RewriteRule .* - [L,R=404]

# Remove virtual language/locale component
RewriteRule ^(en|fr)/(.*)$  $2?lang=$1 [L,QSA]
RewriteRule ^(en|fr)/$  index.php?lang=$1 [L,QSA]

# Rewrite /foo/bar to /foo/bar.php
RewriteRule ^([^.?]+)$ %{REQUEST_URI}.php [L]

Моя проблема в том, что некоторые сайты (например, сообщение Linkedin) каким-то образом автоматически удаляют трейлинг / на индексной странице. Поэтому, если я добавлю ссылку в свой пост domain.com/fr/, они каким-то образом сделают ссылку domain.com/fr, даже если она показывает domain.com/fr/, но 404 как domain.com/fr не существует.

Итак, как я могу перенаправить domain.com/fr на domain.com/fr/ или localhost/mypath/fr (на моей локальной рабочей станции много сайтов) на localhost/mypath/fr/.

Я пробовал что-то вроде:

RewriteRule ^(.*)/(en|fr)$ $1/$2/ [L,QSA,R=301]
RewriteRule ^(en|fr)$ $1/ [L,QSA,R=301]

Но это каким-то образом привело к добавлению полного реального пути к компьютеру в URL-адресе: localhost/mypath/fr становится localhost/pathofthewebserverinmypc/mypath/fr/

Я был бы очень признателен за помощь, так как мне еще предстоит найти правильное правило.

Спасибо

Как установить LAMP Stack 1/2 на Azure Linux VM
Как установить LAMP Stack 1/2 на Azure Linux VM
В дополнение к нашему предыдущему сообщению о намерении Azure прекратить поддержку Azure Database для MySQL в качестве единого сервера после 16...
2
0
59
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий
RewriteRule ^(en|fr)$ $1/ [L,QSA,R=301]

Вам просто не хватает префикса косой черты в строке замены. Следовательно, Apache применяет префикс каталога к относительному URL-адресу, что приводит к неправильному перенаправлению.

Например:

RewriteRule ^(en|fr)$ /$1/ [L,R=301]

Замена теперь является корневым URL-путем, и Apache просто добавляет префикс схемы + имени хоста к внешнему перенаправлению. (Флаг QSA здесь не нужен, так как любая строка запроса добавляется по умолчанию.)

Это нужно сделать до существующих перезаписей (и после правила блокировки для .php запросов).

Обратите внимание, что директивы «внутренней перезаписи» правильны, так как не имеют префикса косой черты.


В стороне:

DirectorySlash Off

Обратите внимание, что если вы отключите косую черту каталога, вы должны убедиться, что автоматически сгенерированные списки каталогов (mod_autoindex) также отключены, в противном случае, если запрашивается каталог без завершающей косой черты, будет создан список каталогов (раскрывая вашу файловую структуру), даже хотя в этом каталоге может быть документ DirectoryIndex.

Например, включите следующее в верхнюю часть файла .htaccess:

# Disable auto-generated directory listings (mod_autoindex)
Options -Indexes

ОБНОВЛЯТЬ:

это работало на рабочем сервере. Так как сайт находится в корне сервера. Не могли бы вы знать, как я могу попытаться «поймать» это на моем локальном хосте? RewriteRule ^(.*)/(en|fr)$ /$1/$2/ [L,R=301] не поймать, но только с RewriteRule ^(en|fr)$ /$1/ [L,R=301]localhost/mypath/fr становится localhost/fr/

Исходя из этого, я предполагаю, что файл .htaccess находится внутри подкаталога /mypath на вашем локальном сервере разработки.

Шаблон RewriteRule (первый аргумент) соответствует URL-пути относительно местоположения файла .htaccess (поэтому он не соответствует /mypath). Затем вы можете использовать серверную переменную REQUEST_URI в подстановке, которая содержит полный URL-путь (относительно корня).

Например:

RewriteRule ^(en|fr)$ %{REQUEST_URI}/ [L,R=301]

Переменная сервера REQUEST_URI уже включает префикс косой черты.

Это правило будет работать как при разработке (в подкаталоге), так и при производстве (в корневом каталоге), поэтому оно должно заменить указанное выше правило, если вам нужно поддерживать обе среды одним файлом .htaccess.

Удивительно, спасибо, это сработало на рабочем сервере. Так как сайт находится в корне сервера. Не могли бы вы знать, как я могу попытаться «поймать» это на моем локальном хосте? RewriteRule ^(.*)/(en|fr)$ /$1/$2/ [L,R=301] dosent catch, но только RewriteRule ^(en|fr)$ /$1/ [L,R=301] localhost/mypath/fr становится localhost/fr/

Fabrice Quenneville 07.02.2023 02:35

@FabriceQuenneville Если сайт (и файл .htaccess) находится в подкаталоге, вам нужно будет изменить правило, чтобы вместо этого использовать переменную сервера REQUEST_URI. Я обновил свой ответ.

MrWhite 07.02.2023 13:12

Удивительно, спасибо, это было сделано как на локальном хосте, так и на производстве.

Fabrice Quenneville 08.02.2023 20:34

Другие вопросы по теме