htaccess cookie +浏览器语言重定向

问题描述

我们正尝试在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之类的路由实际上并不存在于文件夹结构中(因为在进行前端检测之前无法猜测语言)

到目前为止有效的方法:

  1. 您导航至guestbell.com
  2. 您通过htaccess重定向到https
  3. 如果找到文件,则将其送达。
  4. 如果找不到该文件,请提供如下所示的PHP文件:
<?php
$cookieName = "i18next";
$path = rtrim(strtok($_SERVER["REQUEST_URI"],'?'),'/');
$supportedLangs = [
  'en','es',];
$defaultLang = $supportedLangs[0];
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'],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",302);
}
?>

如您所见,它尝试通过Cookie或浏览器语言进行检测(我们知道,此时,URL参数不存在)

这种方法很好用,但是有一个问题。

导航到guestbell.com时(就像大多数人一样),这将导致2次重定向:

  1. HTTP => HTTPS
  2. / => / en

理想情况下,我想消除这种增加的开销,并在一个重定向中完成。唯一的方法(我现在可以想象)是通过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,must-revalidate"
  </filesMatch>
</ifModule>
# END Cache

在这种情况下,另一种方法是将语言检测留在前端,从而完全放弃预渲染。我不太喜欢这个,因为大多数人会导航到页面的根目录而不是/ en并因此失去性能。但是让我担心的是,由于多次重定向,性能仍然会丢失。

我的问题是: 是否可以在htaccess中结合HTTP => HTTPS来进行cookie和浏览器语言重定向?如果是这样,您能否提供帮助以实现这种功能?如果不是,您是否可以分享实现这一目标的最佳方法,或者选择验证我们使用PHP的方法“足够好”?

非常感谢。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...