我们正尝试在https://guestbell.com/处解决“正确方式”的语言重定向。首先是一些成语:
a)每条路线都有一个用于标识语言的起始URL参数。例如https://guestbell.com/en(英语)和https://guestbell.com/es(西班牙语)。还有https://guestbell.com/en/pricing等。
b)您也可以省略此参数,例如https://guestbell.com/pricing。然后检测语言(cookie,浏览器语言,qs参数或URL参数)并将其添加到URL。 Page是SPA中的反应,检测是通过i18next库完成的。
c)每个可能的页面都预先通过静态服务器提供的HTML文件呈现。
请注意,由于路由是预先渲染的,因此https://guestbell.com/pricing之类的路由实际上并不存在于文件夹结构中(因为在进行前端检测之前无法猜测语言)
到目前为止有效的方法:
<?php
$cookieName = "i18next";
$path = rtrim(strtok($_SERVER["REQUEST_URI"], '?'), '/');
$supportedLangs = [
'en',
'es',
];
$defaultLang = $supportedLangs[0];
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
if(isset($_COOKIE[$cookieName])) {
$lang = $_COOKIE[$cookieName];
}
$finalLang = $lang;
if (!in_array($lang, $supportedLangs)) {
$finalLang = $defaultLang;
}
$newPath = $finalLang . $path . '.html';
if (file_exists($newPath) || empty($path)) {
$newPath = $finalLang . $path;
header("Location: $newPath", true, 302);
} else {
$newPath = $finalLang . '/404';
header("Location: $newPath", true, 302);
}
?>
如您所见,它尝试通过Cookie或浏览器语言进行检测(我们知道,此时,URL参数不存在)
这种方法很好用,但是有一个问题。
导航到guestbell.com时(就像大多数人一样),这将导致2次重定向:
理想情况下,我想消除这种增加的开销,并在一个重定向中完成。唯一的方法(我现在可以想象)是通过htaccess进行的。问题是我不知道这是否可能。
为完成起见,这是当前的htaccess:
ErrorDocument 404 /404.html
#This is extremely important as it disables rewriting route from en => en/ and then 403-ing on directory
#https://stackoverflow.com/questions/28171874/mod-rewrite-how-to-prioritize-files-over-folders
DirectorySlash Off
# BEGIN WWW omit
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^ %{REQUEST_SCHEME}://%1%{REQUEST_URI} [R=301,L]
</IfModule>
# END WWW omit
# BEGIN HTTPS redirect
<IfModule BEGIN HTTPS redirectfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{ENV:HTTPS} !=on
RewriteRule ^.*$ https://%{SERVER_NAME}%{REQUEST_URI} [R,L]
</IfModule>
# END HTTPS redirect
# BEGIN Omit extension
<ifModule mod_rewrite.c>
#remove html file extension-e.g. https://example.com/file.html will become https://example.com/file
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.html [NC,L]
</ifModule>
# END Omit extension
# BEGIN File detection
<ifModule mod_rewrite.c>
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.php - that file then takes care of language redirection
RewriteRule ^ /index.php
</ifModule>
# END File detection
# BEGIN Compress text files
<ifModule mod_deflate.c>
<filesMatch "\.(css|js|x?html?|php)$">
SetOutputFilter DEFLATE
</filesMatch>
</ifModule>
# END Compress text files
# BEGIN Cache
<ifModule mod_headers.c>
<filesMatch "\\.(ico|pdf|flv|jpg|jpeg|png|gif|swf|svg|mp4)$">
Header set Cache-Control "max-age=31536000, public"
</filesMatch>
<filesMatch "\\.(css)$">
Header set Cache-Control "max-age=31536000, public"
</filesMatch>
<filesMatch "\\.(js)$">
Header set Cache-Control "max-age=31536000, private"
</filesMatch>
<filesMatch "\\.(xml|txt)$">
Header set Cache-Control "max-age=2592000, public, must-revalidate"
</filesMatch>
<filesMatch "\\.(html|htm|php)$">
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
</filesMatch>
<filesMatch "sw.js$">
Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
</filesMatch>
</ifModule>
# END Cache
在这种情况下,另一种方法是将语言检测留在前端,从而完全放弃预渲染。我不太喜欢这个,因为大多数人会导航到页面的根目录而不是/ en并因此失去性能。但是让我担心的是,由于多次重定向,性能仍然会丢失。
我的问题是: 是否可以在htaccess中结合HTTP => HTTPS来进行cookie和浏览器语言重定向?如果是这样,您能否提供帮助以实现这种功能?如果不是,您是否可以分享实现这一目标的最佳方法,或者选择验证我们使用PHP的方法“足够好”?
非常感谢。