nginx - 从上游服务器读取自定义标头

Posted

技术标签:

【中文标题】nginx - 从上游服务器读取自定义标头【英文标题】:nginx - read custom header from upstream server 【发布时间】:2012-09-08 00:43:57 【问题描述】:

我正在使用 nginx 作为反向代理,并尝试从上游服务器 (Apache) 的响应中读取自定义标头,但没有成功。 Apache 响应如下:

HTTP/1.0 200 OK
Date: Fri, 14 Sep 2012 20:18:29 GMT 
Server: Apache/2.2.17 (Ubuntu)
X-Powered-By: php/5.3.5-1ubuntu7.10
Connection: close
Content-Type: application/json; charset=UTF-8
My-custom-header: 1

我想从 My-custom-header 中读取值并在 if 子句中使用它:

location / 
    // ...
    // get My-custom-header value here
    // ...

这可能吗?提前致谢。

【问题讨论】:

【参考方案1】:

这不仅可能,而且很简单:

在 nginx 中,响应标头值可通过变量(每个标头一个)获得。 有关这些变量的详细信息,请参阅http://wiki.nginx.org/HttpCoreModule#.24sent_http_HEADER。

在您的示例中,变量为 $sent_http_My_custom_header。

【讨论】:

事实证明,这也不正确。 OP 要求读取响应标头的值。你应该使用$sent_http_my_custom_header。 nginx.org/en/docs/http/ngx_http_core_module.html#var_sent_http_ 如果您需要上游响应标头,请检查下面的@dev-gosain 答案 答案是错误的。询问的人正在尝试从 upstream 服务器访问标头。正确答案是***.com/a/30879181/111995 这个答案在 2015 年被编辑更多弄错了,$sent_http_$http_ 取代。我现在已经恢复了那个编辑。答案仍然不正确。 $sent_http_name 是一个 client 响应头,从 NGINX 发送到客户端。 OP 要求 upstream 响应标头,即从上游服务器返回 NGINX 的响应中的条目。两者之间的区别在于某些标头没有从上游转发到客户端。此外,您不能在if 条件中使用响应标头变量【参考方案2】:

我遇到了同样的问题。我尝试了$http_my_custom_header$sent_http_my_custom_header,但它对我不起作用。

虽然通过使用$upstream_http_my_custom_header 解决了这个问题。

【讨论】:

此处记录了适当的变量$upstream_http_name 模式:nginx.org/en/docs/http/ngx_http_upstream_module.html#variables【参考方案3】:

使用 NGINX 作为代理时,有 组标头:

client -> nginx: 客户端请求标头 nginx -> upstream: 上游 request 标头 upstream -> nginx: 上游响应标头 nginx -> client: 客户端响应标头

您似乎在询问上游响应标头。这些可以在$upstream_http_<i>name</i> variables 中找到。

但是,请注意,任何 响应 标头仅在收到上游服务器响应的标头之后设置。任何if directives 在发送上游请求之前运行,并且无法访问任何响应标头!换句话说,if 指令在收到客户端请求之后,在发出上游请求之前运行。

如果您需要更改响应的处理方式,您可以使用 map directive 然而基于响应标头设置变量,然后在 add_header(设置客户端响应标头)、log_format 或任何其他变量中使用这些变量在响应阶段处于活动状态的其他指令(内部命名为NGX_HTTP_CONTENT_PHASE and NGX_HTTP_LOG_PHASE phases)。对于更复杂的控制,您必须使用脚本插件,例如 Lua module(例如使用 header_filter_by_lua_block directive)。

要读取或设置单个标题,请使用:

from to type read (variable) write (directive)
client nginx request $http_<i>name</i>
ngnix upstream request proxy_set_header
upstream nginx response $upstream_http_<i>name</i>
nginx client response $sent_http_<i>name</i> add_header

NGINX 使用各种proxy_ directives 将某些标头从客户端请求复制到上游请求,并从上游响应复制到客户端响应,为您提供省略或明确包含任一方向的标头的选项。因此,如果上游响应标头仅在 $upstream_http_<i>name</i> 变量中找到,那么这些标头不会专门复制到客户端响应中,并且可用的 $sent_http_<i>name</i> 变量集将包括任何 extra 标头设置上游响应中不存在的 NGINX。

【讨论】:

【参考方案4】:

使用 $http_MY_CUSTOM_HEADER

你可以写一些类似的东西

set my_header $http_MY_CUSTOM_HEADER;
if($my_header != 'some-value') 
#do some thing;

【讨论】:

man 说 - 变量名称的最后一部分是转换为 小写 的字段名称,其中破折号替换为下划线。

以上是关于nginx - 从上游服务器读取自定义标头的主要内容,如果未能解决你的问题,请参考以下文章

Nginx Web 服务器错误 - 上游从上游读取响应标头时发送的标头太大

Nginx上游过早关闭连接,同时从上游读取响应标头,用于大型请求

AWS Nginx“从上游读取响应标头时上游过早关闭连接”

错误:从上游 [uWSGI/Django/NGINX] 读取响应标头时,上游过早关闭连接

上游从上游、客户端(nginx、varnish)读取响应头时发送了太大的头

nginx uwsgi websockets 502 Bad Gateway上游过早关闭连接,同时从上游读取响应标头