Я делаю многоязычный динамический сайт, который создает виртуальный путь для каждого языка.
Итак, французские страницы идут по адресу 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/
Я был бы очень признателен за помощь, так как мне еще предстоит найти правильное правило.
Спасибо
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
.
@FabriceQuenneville Если сайт (и файл .htaccess
) находится в подкаталоге, вам нужно будет изменить правило, чтобы вместо этого использовать переменную сервера REQUEST_URI
. Я обновил свой ответ.
Удивительно, спасибо, это было сделано как на локальном хосте, так и на производстве.
Удивительно, спасибо, это сработало на рабочем сервере. Так как сайт находится в корне сервера. Не могли бы вы знать, как я могу попытаться «поймать» это на моем локальном хосте?
RewriteRule ^(.*)/(en|fr)$ /$1/$2/ [L,R=301]
dosent catch, но толькоRewriteRule ^(en|fr)$ /$1/ [L,R=301]
localhost/mypath/fr становится localhost/fr/