304响应没有为带有mod_头的apache设置自定义头 服务器管理员webmaster@dev.dom.com DocumentRoot“C:/Program Files/Apache软件基金会/Apache2.2/htdocs” ServerName dev.dom.com ServerAlias dev.dom.com ErrorLog“logs/dev.dom.com error.log” CustomLog“logs/dev.dom.com access.log”通用 PassEnv簇 标头始终设置X-簇“%{Cluster}e”

304响应没有为带有mod_头的apache设置自定义头 服务器管理员webmaster@dev.dom.com DocumentRoot“C:/Program Files/Apache软件基金会/Apache2.2/htdocs” ServerName dev.dom.com ServerAlias dev.dom.com ErrorLog“logs/dev.dom.com error.log” CustomLog“logs/dev.dom.com access.log”通用 PassEnv簇 标头始终设置X-簇“%{Cluster}e”,apache,http-headers,http-status-code-304,Apache,Http Headers,Http Status Code 304,这是我的配置。我有一个环境变量,它告诉我我在哪个集群上,它在“X-cluster”中作为头传递。对于200或404响应,这会返回很好的结果,但是304 Not Modified响应永远不会返回头,即使它返回其他适当的Apache头 如何在304响应期间设置头?Apache明确禁止修改304响应中的响应头以符合http规范。此类响应的名称为“未修改”。您可以使用Apache的过滤器体系结构、编写自定义模块或使用mod_perl来修改此行为,但这很可能是错误的。根据当前的HTTP规范,304 Not

这是我的配置。我有一个环境变量,它告诉我我在哪个集群上,它在“X-cluster”中作为头传递。对于200或404响应,这会返回很好的结果,但是304 Not Modified响应永远不会返回头,即使它返回其他适当的Apache头


如何在304响应期间设置头?

Apache明确禁止修改304响应中的响应头以符合http规范。此类响应的名称为“未修改”。您可以使用Apache的过滤器体系结构、编写自定义模块或使用mod_perl来修改此行为,但这很可能是错误的。

根据当前的HTTP规范,
304 Not Modified
响应不应返回实体头(少数特定异常除外)。引述自:

如果使用强缓存验证器,则响应不应包括其他实体头。 否则(即,使用弱验证器的条件GET),响应不得包括其他实体头;这可以防止缓存实体和更新的头之间的不一致

不幸的是,所有的扩展头都是空的

然而,展望未来,在打算取代RFC 2616的HTTPbis规范草案中,规则要宽松得多。引述自:

因为304响应的目标是最小化信息传输 如果收件人已经有一个或多个缓存表示,则 发件人不应生成除 以上列出的字段,除非出于以下目的存在所述元数据: 指导缓存更新

因此,如果您正在设置一个不会被分类为表示元数据的自定义头,那么我希望在新规则下它被认为是合法的

也就是说,无论这些规范中写了什么,您仍然必须处理Apache可以支持的内容。从我在源代码中看到的情况来看,304响应中仍然不支持自定义头

过滤头的位置在文件中的ap_http_header_filter函数中:

更具体地说,此代码:

<VirtualHost *:80>
    ServerAdmin webmaster@dev.dom.com
    DocumentRoot "C:/Program Files/Apache Software Foundation/Apache2.2/htdocs"
    ServerName dev.dom.com
    ServerAlias dev.dom.com
    ErrorLog "logs/dev.dom.com-error.log"
    CustomLog "logs/dev.dom.com-access.log" common
    PassEnv CLUSTER
    Header always set X-Cluster "%{CLUSTER}e"
</VirtualHost>
当返回“Not Modified”响应(304)时,上面的头列表是唯一允许通过的头(除了一些自动生成的头,如Date和Server)。从我所看到的情况来看,似乎没有一种简单的方法可以挂接到这个代码中来改变行为

底线是,目前在Apache中这仍然是不可能的。至少有人请求支持其他标头,但这是专门针对CORS标头的。不过,幸运的是,这可能会鼓励他们更开放地支持自定义标题

但在这之前,我能建议的唯一解决方案是自己修补服务器。如果不想从源代码重建,甚至可以直接修补二进制文件。例如,如果您只需要支持一个或两个新的头,您可以替换一些不太可能使用的现有头(例如Set-Cookie2,它已经过时)

只需在ApacheBin目录中搜索要替换的头名称(在Windows上,应该在libhttpd.dll中找到它们)。然后使用二进制编辑器用新的头名称替换以null结尾的字符串(当然,它需要与要替换的头的长度相同或更短)


我不知道其他的操作系统,但我已经在Windows上测试过了,它看起来确实有效。这显然是一个可怕的黑客,但如果你足够绝望,你可能会认为这是一个选项。

远投,但你找到解决的办法吗?
if (r->status == HTTP_NOT_MODIFIED) {
    apr_table_do((int (*)(void *, const char *, const char *)) form_header_field,
                 (void *) &h, r->headers_out,
                 "Connection",
                 "Keep-Alive",
                 "ETag",
                 "Content-Location",
                 "Expires",
                 "Cache-Control",
                 "Vary",
                 "Warning",
                 "WWW-Authenticate",
                 "Proxy-Authenticate",
                 "Set-Cookie",
                 "Set-Cookie2",
                 NULL);
}