【发布时间】:2013-01-08 04:35:48
【问题描述】:
我想为从 nginx 后面的服务器收到的响应添加一个自定义标头。
虽然add_header 适用于 nginx 处理的响应,但在使用 proxy_pass 时它什么也不做。
【问题讨论】:
-
因此,您将请求传递给代理,该代理设置响应,并且在此响应中您希望在将其发送给用户之前添加您的自定义标头,对吗?
标签: nginx http-headers proxypass
我想为从 nginx 后面的服务器收到的响应添加一个自定义标头。
虽然add_header 适用于 nginx 处理的响应,但在使用 proxy_pass 时它什么也不做。
【问题讨论】:
标签: nginx http-headers proxypass
add_header 与proxy_pass 一起使用也同样有效。我今天刚刚设置了一个配置,我已经使用了该指令。不过,我不得不承认,我在设置它时也遇到了困难,但并没有确切地回忆起原因。
现在我有一个有效的配置,它包含以下(以及其他):
server {
server_name .myserver.com
location / {
proxy_pass http://mybackend;
add_header X-Upstream $upstream_addr;
}
}
在 nginx 1.7.5 add_header 之前只对成功响应起作用,与Sebastian Goodman in his answer 提到的HttpHeadersMoreModule 形成对比。
由于 nginx 1.7.5 您可以使用关键字 always 来包含自定义标头,即使在错误响应中也是如此。例如:
add_header X-Upstream $upstream_addr always;
限制:您不能使用 add_header 覆盖 server 标头值。
【讨论】:
add_header X-Upstream $upstream_addr always;
X-Upstream: 10.10.10.10 vs X-Upstream: 53c2d28edefdf501ab7c92e02a0c1687(md5 可能对掩盖基础设施没有帮助,但它传达了这个想法)。
add_header 指令的一个示例。您根本不需要发送它们。
有一个名为HttpHeadersMoreModule 的模块可以让您更好地控制标题。它不附带 Nginx,需要额外安装。有了它,你可以做这样的事情:
location ... {
more_set_headers "Server: my_server";
}
这将“将服务器输出标头设置为任何状态代码和任何内容类型的自定义值”。它将替换已设置的标头,如果未设置则添加它们。
【讨论】:
Secure 和 HttpOnly 标志?目标响应 cookie 仅具有 cookie name 和 expire 属性。
使用add_header 添加标头可以很好地使用代理传递,但如果响应中存在现有标头值,它将堆叠这些值。
如果您想设置或替换标头值(例如替换 Access-Control-Allow-Origin 标头以匹配您的客户端以允许跨源资源共享),您可以执行以下操作:
# 1. hide the Access-Control-Allow-Origin from the server response
proxy_hide_header Access-Control-Allow-Origin;
# 2. add a new custom header that allows all * origins instead
add_header Access-Control-Allow-Origin *;
所以proxy_hide_header 与add_header 相结合让您能够设置/替换响应标头值。
类似的答案可以在here on ServerFault找到
注意: proxy_set_header 用于在进一步发送请求之前设置请求标头,而不是用于设置响应标头(标头的这些配置属性可能有点混乱)。
【讨论】:
proxy_set_header 的评论帮助我理解了这两个电话之间的区别,谢谢 :)
正如奥利弗所写:
add_header与proxy_pass一起使用也一样。
但是,正如 Shane 所写,从 Nginx 1.7.5 开始,您必须通过 always 才能让 add_header 处理错误响应,如下所示:
add_header X-Upstream $upstream_addr always;
【讨论】:
你可以试试这个解决方案:
当您使用 proxy_pass 时,在您的 location 块中执行以下操作:
location ... {
add_header yourHeaderName yourValue;
proxy_pass xxxx://xxx_my_proxy_addr_xxx;
# Now use this solution:
proxy_ignore_headers yourHeaderName // but set by proxy
# Or if above didn't work maybe this:
proxy_hide_header yourHeaderName // but set by proxy
}
我不确定这是否正是您所需要的,但请尝试对这种方法进行一些操作,也许结果会适合您的问题。
你也可以使用这个组合:
proxy_hide_header headerSetByProxy;
set $sent_http_header_set_by_proxy yourValue;
【讨论】:
location / { proxy_pass http://127.0.0.1:8080/; proxy_hide_header "Access-Control-Allow-Origin"; if ($http_origin ~* "^https://(example.com|www.example.com)$") { add_header Access-Control-Allow-Origin "$http_origin"; } }