1

我有一个小网站,可以根据以下标准(优先顺序递增)选择不同的语言:

  1. Accept-Language浏览器发送的
  2. 指定首选语言的 cookie
  3. 最后包含语言首选项的请求路径

该站点本身仅包含静态 HTML 页面,并且我希望尽可能保持这种状态。我通过 和以下文件(缩短为省略语言和字符集的声明)实现了mod_negotiation语言mod_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

自八月左右以来一直运行良好,以允许以下情况:

  1. 不存在 cookie,Accept-Language接管(感谢MultiViews
  2. Cookie 存在,将使用 cookie 的语言 ( prefer-language)
  3. 请求路径是/es或类似的,将用于 (a) 设置 cookie 和 (b) 设置prefer-language为该值。

现在,我在网站上还有一些资源,多亏了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 监狱内),所以我无法启用重写日志(因为我什至不知道文件所在的物理路径);此外,它显然似乎忽略了环境变量,并且出于某种原因仅使用 cookie 设置首选语言。到目前为止,我还没有弄清楚为什么。有什么帮助吗?

4

1 回答 1

1

RewriteRule我现在通过混合和之间的语言选择解决了这个问题SetEnvIf

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_,但至少它现在可以工作。

于 2011-11-14T02:22:19.323 回答