当RewriteCond匹配时,mod_rewrite不发送Vary:accept-language

时间:2010-09-13 07:02:02

标签: mod-rewrite apache2 vary

我有一个重写规则,重定向到/如果没有接受语言,有人试图访问?lang=en。它工作正常,除了返回的标头。回复中缺少Vary: accept-language

RewriteCond %{HTTP:Accept-Language} ^$  
RewriteCond %{QUERY_STRING}         ^lang=en  
RewriteRule ^$                      http://www.example.com/?     [R=301,L]

Apache文档指定:

如果在某个条件中使用HTTP标头,则此标头会添加到响应的Vary标头中,以防条件评估为请求的true。如果请求的条件评估为false,则不会添加它。

条件肯定是匹配和重定向,所以我不明白为什么Apache没有添加语言各不相同。人们可以看到为什么如果代理要缓存那么这将是一个真正的问题?lang = en总是重定向到/不管发送的接受语言头。

3 个答案:

答案 0 :(得分:10)

答案 1 :(得分:1)

您可能希望尝试使用以下内容作为解决方法:

<LocationMatch "^.*lang\=">
    Header onsuccess merge Vary "Accept-Language"
</LocationMatch>

答案 2 :(得分:0)

要在 redirect 响应 only 上专门设置 Vary: Accept-Language HTTP 响应标头(这是这里的预期),您需要设置一个环境变量(例如,VARY_ACCEPT_LANGUAGE)作为重定向规则的一部分,并使用它通过 Header 指令有条件地设置标头。

您还需要将 always condition(与默认的 onsuccess 相反)与 Header 指令一起使用,以便在 3xx 上进行设置响应(即非 200 个响应)。

例如:

# Redirect requests that have an empty Accept-Language header and "lang=en" is present
RewriteCond %{HTTP:Accept-Language} ^$  
RewriteCond %{QUERY_STRING} ^lang=en  
RewriteRule ^$ /? [E=VARY_ACCEPT_LANGUAGE:1,R=301,L]

# Set/Merge "Vary" header on Accept-Language redirect
Header always merge Vary "Accept-Language" env=VARY_ACCEPT_LANGUAGE

然而,Vary 标头不应只在重定向响应上设置(当 Accept-Language 标头为空时),它需要在对 {{1} 请求的所有响应上设置},无论 /?lang=en HTTP 请求标头实际设置为什么。因此,依靠 Apache 仅使用重定向来设置此标头是不够的(即使它确实按照最初预期在响应上设置了标头)。

为了在对 Accept-Language 请求的所有响应(包括重定向)上设置适当的 Vary 标头,请执行以下操作:

/?lang=en

但是请注意,如果您有额外的内部重写指令导致重写引擎重新开始,那么 env var # Set env var if "/?lang=en" is requested RewriteCond %{QUERY_STRING} ^lang=en RewriteRule ^$ - [E=VARY_ACCEPT_LANGUAGE:1] # Redirect requests that have an empty Accept-Language header and "lang=en" is present RewriteCond %{HTTP:Accept-Language} ^$ RewriteCond %{QUERY_STRING} ^lang=en RewriteRule ^$ /? [R=301,L] # Set/Merge "Vary" header on all responses from "/?lang=en" Header always merge Vary "Accept-Language" env=VARY_ACCEPT_LANGUAGE 将重命名为 VARY_ACCEPT_LANGUAGE 并且上面的 REDIRECT_VARY_ACCEPT_LANGUAGE 指令将不会成功。您可能需要一个额外的指令来处理这个问题。例如:

Header