【问题标题】:How to set HTTP Header only for existing files using in Apache conf如何仅在 Apache conf 中为现有文件设置 HTTP 标头
【发布时间】:2011-10-21 00:33:17
【问题描述】:
我正在使用 Apache 提供文件和应用请求,应用请求使用 RewriteRule 将匹配模式的 url 发送到我的应用服务器。
我想仅为与上面的 RewriteConds 不匹配的请求设置特定的 HTTP 标头(缓存控制)。有什么方法可以在不使用.htaccess 文件的情况下做到这一点?
我尝试将Header set 指令放在RewriteRule(它使用L 标志)之后,但仍然会应用标头。
【问题讨论】:
标签:
caching
header
apache
【解决方案1】:
你真的应该发布你的 rewriteRules。
我们当然可以为此做些什么。我想的第一件事是在匹配rewriteRules 中设置一个环境变量(所以一组rewriteCond,反转以前的),使用[E=myvar:myvalue] 标签;并使用 Header 指令的最后一个可用参数 [env=myvar] 来条件设置此 Header。
然后你说:
有什么方法可以在不使用 .htaccess 文件的情况下做到这一点?
好吧,RewriteRules 和 .htaccess 文件是松散相关的。您在 .htaccess 中设置的任何内容都更适合 <Directory> 指令,并在您的 VirtualHost 上使用漂亮的 AllowOverride None 以防止来自 apache 的大量 IO 操作,试图在每个请求中读取一堆 .htaccess 文件。
第二件事,你说:
我尝试在 RewriteRule 之后放置 Header set 指令
(使用 L 标志)
[L] 标志可以防止同一目录上的多个 RewriteRules 一个接一个地应用,因此它们现在不会被直接链接。但事实上,在你的 rewriteRule 结束 ([L]) 之后,rewriteRule 的输出会被重新应用到目录中,看看是否仍然应该应用任何 RewriteRule(可能是同一个)。
这就是我们有时会看到太多内部重定向消息的原因。
看到它发生的唯一方法是在 VirtualHost 上使用 RewriteLog /a/file.log 和 RewriteLogLevel 9(有时会有很多惊喜,某些规则有时会使用太多递归)。
众所周知的一个好的 RewriteCond 是:
RewriteCond %{ENV:REDIRECT_STATUS} ^$
任何带有此 rewriteCond 前缀的规则只会在您第一次进入目录时应用,在您的规则结束后(可能带有 [L] 或因为没有更多规则),结果将在目录规则,但环境变量 REDIRECT_STATUS 不为空。如果设置了这个 env 变量,这个 Condition 告诉 mod-rewrite 避免该规则。