我有一个重写规则,重定向到/如果没有接受语言,有人试图访问?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总是重定向到/不管发送的接受语言头。
答案 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