通过MultiViews进行语言选择仅在请求其他资源时有效

时间:2011-11-13 13:33:30

标签: .htaccess mod-rewrite apache2 multiviews mod-negotiation

我有一个基于以下标准选择的不同语言的小网站(增加优先顺序):

    浏览器发送的
  1. Accept-Language
  2. 指定首选语言的Cookie
  3. 最后包含语言首选项的请求路径
  4. 网站本身只包含静态HTML网页,我希望尽可能保持这种状态。我通过mod_negotiationmod_rewrite和以下.htaccess文件(缩写为省略语言和字符集声明)实现了语言选择:

    Options FollowSymLinks MultiViews
    DirectoryIndex index
    
    Header set Pragma no-cache
    
    RewriteEngine on
    RewriteRule ^([a-zA-Z-]{2,5})$ index [CO=language:$1:.example.com:525600,E=LANG:$1]
    
    SetEnvIf Cookie "language=([a-zA-Z-]+)" COOKIE_LANG=$1
    
    SetEnvIf COOKIE_LANG (.+) prefer-language=$1
    SetEnvIf REDIRECT_LANG (.+) prefer-language=$1
    
    # plenty of AddLanguage and AddCharset calls
    
    LanguagePriority en-us
    DefaultLanguage en-us
    ForceLanguagePriority Prefer Fallback
    

    自8月左右以来一直运作正常,以便实现以下目标:

    1. 不存在Cookie,Accept-Language接管(感谢MultiViews
    2. Cookie存在,将使用Cookie的语言(prefer-language
    3. 请求路径为/es或类似,用于(a)设置Cookie和(b)将prefer-language设置为该值。
    4. 现在,我在网站上有更多资源,感谢MultiViews,可以通过/resource代替/resource.html进行选择,内容协商和Cookie选项仍可以正常使用在这里选择适当的语言。

      现在我想扩展URI处理,以便像/resource/en之类的东西直接选择特定语言的资源,这样这不仅适用于/。我尝试了以下RewriteRule

      RewriteRule ^(([^/]+)/)?([a-zA-Z-]{2,5})$ /$2 [CO=language:$3:.example.com:525600,E=LANG:$3]
      

      并且它的工作原理是发送正确的资源并设置正确的cookie,但显然不再从环境变量中获取首选语言。现在唯一迫使语言选择的是cookie,但是在那个请求上仍然和以前一样,所以在刷新页面之前我不会看到新语言。到目前为止,我对规则的任何尝试都没有对这种行为产生影响。有趣的是,通过这个规则,上面记录的旧行为仍然可以正常工作。只有当我要求与/不同的东西时,它才能做出奇怪的事情。

      这是在共享主机上(在FreeBSD jail中)所以我无法启用重写日志(因为我甚至不知道文件所在的物理路径);此外,它显然似乎忽略了环境变量,并且由于某种原因仅使用cookie来设置首选语言。到目前为止我还没弄清楚为什么。有什么帮助吗?

1 个答案:

答案 0 :(得分:1)

我现在通过混合RewriteRuleSetEnvIf之间的语言选择来解决问题:

SetEnvIf Cookie "language=([a-zA-Z-]+)" prefer-language=$1
SetEnvIf REDIRECT_prefer-language "(.+)" prefer-language=$1
SetEnvIf Request_URI "/([a-zA-Z-]{2,5})$" prefer-language=$1

RewriteRule "^(([^/]+)/)?([a-zA-Z-]{2,5})$" /$2 [CO=language:$3:.example.com:525600]

规则现在只设置cookie并指向正确的资源,而语言选择则通过匹配请求URI来处理。仍然感觉很奇怪,特别是因为当需要以REDIRECT_为前缀时它不容易看到,但至少它现在有用。