【问题标题】:What is the difference between "always" and "onsuccess" in Apache's Header config?Apache 的 Header 配置中的“always”和“onsuccess”有什么区别?
【发布时间】:2016-08-27 17:37:47
【问题描述】:

我有一个网站,其中在/etc/apache2/sites-enabled/ 中定义了虚拟主机,并使用always 选项设置了标头,如下所示:

Header always set X-Frame-Options DENY

如果我现在在网站的根文件夹中使用.htaccess 设置相同的标头,但没有always,那么标头会在服务器响应中返回两次。

.htaccess(以及其他)中的设置:

Header set X-Frame-Options DENY

服务器的响应:

HTTP/1.1 200 OK
Date: Mon, 02 May 2016 16:02:29 GMT
Server: Apache/2.4.10 (Debian)
X-Frame-Options: DENY
Cache-Control: no-cache, no-store, must-revalidate, private
Pragma: no-cache
X-XSS-Protection: 1
X-Content-Type-Options: nosniff
Last-Modified: Mon, 02 May 2016 15:03:42 GMT
Accept-Ranges: bytes
Content-Length: 0
X-Frame-Options: DENY
X-XSS-Protection: 1
X-Content-Type-Options: nosniff
Cache-Control: no-cache, no-store, must-revalidate, private
Pragma: no-cache
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: text/html

Apache 文档说,如果没有 always 选项,则使用默认值 onsuccess。但是他们也说“... onsuccess 的默认值不会将操作限制为具有 2xx 状态代码的响应...” (http://httpd.apache.org/docs/current/en/mod/mod_headers.html#header)。

但是如果我不添加always,那么像 301s 和 404s 这样的错误页面就不会设置标题。另一方面,如果我确实添加了always,那么如果我在.htaccess 中使用默认值(即onsuccess),那么标题可能会设置两次。正如文档所述:“在某些情况下,在两种情况下重复此指令是有意义的,因为就现有标头而言,它始终不是 onsuccess 的超集”。两次设置标头对于 HTTP 响应并不总是有效,请参阅https://stackoverflow.com/a/4371395/641481。所以我想自然而然地避免它。

我现在的问题是:我应该在什么时候使用onsuccess(即默认值)以及什么时候使用always?我必须承认,即使在阅读了 Apache 文档几次之后,我也并不完全理解这一点。务实地说,似乎总是使用always 会导致正确/预期的行为。

我也不明白为什么 Apache 会在 alwaysonsuccess 中设置标头两次。对我来说这似乎是错误的,但这一定有充分的理由,因为我认为 Apache 开发人员比我对 HTTP 了解的多得多;-)

【问题讨论】:

    标签: apache .htaccess http http-headers virtualhost


    【解决方案1】:

    我们为我们的 Apache 网络服务器使用带有 Dispatcher [缓存] 模块的 Adob​​e Experience Manager。 Adobe 最近更改了以下代码。本质上,我相信您可能需要使用“expr=”语法来确保尚未设置该值。这应该消除重复。

    这是来自 Adob​​e 的参考代码:

    原始配置:Header always append X-Frame-Options SAMEORIGIN

    新配置:Header merge X-Frame-Options SAMEORIGIN "expr=%{resp:X-Frame-Options}!='SAMEORIGIN'"

    当我询问时,Adobe 给了我以下原因。感谢 Adob​​e。

    说明: 使用“合并”而不是“附加”可以防止条目的值被多次添加到标题中。

    expr=expression:当且仅当 expression 计算结果为 true 时才应用该指令。表达式语法和评估的详细信息记录在 ap_expr 文档中。 “expr”正在查看来自服务器(Publisher Application Server)的响应标头,以确保它不包含 SAMEORIGIN。这样可以确保 SAMEORGIN 在发送回请求客户端的响应标头中不会重复。

    这是必需的,因为测试发现,当 AEM 包含此标头时,即使使用合并选项,Apache 也会复制 SAMEORIGIN 值。 Apache 在从自身获取标头时能够正确合并,但是因为第一个标头是由 AEM 在 Apache 实例之外设置的,所以它变得很奇怪(并且需要额外的表达式)。

    他们似乎也不使用“总是”和 merge+expr 语法。也许还可以解决 Apache 的怪异问题。

    PS...记得在您的情况下将“SAMEORIGIN”更改为“DENY”。

    【讨论】:

      【解决方案2】:

      这只是部分答案,因为它不包括 onsuccess 属性。它基于使用在 Ubuntu 14 操作系统上运行的 apache 2.4.7 的经验。希望对您有所帮助。

      Header 指令的纯 set 参数(没有属性)通过强制 Header set 的参数成为唯一传递的参数来覆盖任何 always 属性。如果相同的指令出现在目录中,即基于文件系统的 .htaccess 文件,它优先于与该目录相关的虚拟主机定义文件中记录的相同指令。如果属性 always 被额外注明,它的效果是相同指令的任何相同或不同的符号被添加到服务器答案中,而不是覆盖/替换它。

      可能onsuccess 属性(遗憾的是我现在没有时间探索)可能与always 属性类似地处理。

      【讨论】:

      • 经过大量测试,不,set always 不会覆盖 set
      • @user5994461:您似乎误解了我的话:第一段的第一句话说“标题'set'覆盖'always'”,但它没有说“'always'覆盖'set' ”。你的测试只是证明了我的帖子。请恢复投票。
      • 不正确。 Set 不会总是覆盖,也总是不会覆盖 set。它们独立工作,如果两者都使用,http响应会得到2个headers。
      • @user5994461:6 月 23 日“不覆盖”,6 月 26 日“不总是覆盖”?您是否在上下文中仔细阅读了问答?你没有提供任何细节,只是假设。我们应该在这里搜索并提供帮助一个事实基础。
      • 我测试了不同的设置组合。我将解释与更多细节联系起来,但它已经被堆栈溢出纳粹删除了。很抱歉,堆栈溢出对于不重要的问题和答案很糟糕。
      猜你喜欢
      • 1970-01-01
      • 2015-03-11
      • 2018-02-14
      • 2017-03-24
      • 1970-01-01
      • 2012-05-04
      • 2015-08-28
      • 2016-06-23
      • 2016-06-05
      相关资源
      最近更新 更多