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

111

我正在使用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
    // ...
}

这可能吗?

5个回答

111

不仅是可能的,而且很容易:

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

在您的例子中,变量将是$sent_http_My_custom_header。


16
事实证明,这也是不正确的。 OP要求读取响应头的值。您应该使用$sent_http_my_custom_header。参见:http://nginx.org/en/docs/http/ngx_http_core_module.html#var_sent_http_ - Nathan
1
如果需要上游响应头,请查看@dev-gosain的答案 - filimonov
22
答案错误。提问者试图从上游服务器访问标头。正确的答案是https://dev59.com/nmcs5IYBdhLWcg3w-Yv4#30879181。 - geekQ
1
这个回答在2015年的编辑中变得更加错误,其中$sent_http_被替换为$http_。我现在已经恢复了那个编辑。答案仍然是不正确的。$sent_http_name是一个客户端响应头,从NGINX发送到客户端。OP正在寻求上游响应头,即从上游服务器返回到NGINX的响应中的条目。两者之间的区别很重要,因为某些标头不会从上游转发到客户端。此外,您不能在if条件中使用响应标头变量 - Martijn Pieters
1
请更新链接,它无法使用。 - undefined

64
使用NGINX作为代理时,有四个组的标头:
  • client -> nginx:客户端请求标头
  • nginx -> upstream:上游请求标头
  • upstream -> nginx:上游响应标头
  • nginx -> client:客户端响应标头

您似乎在询问上游响应标头。这些可以在$upstream_http_name变量中找到。

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

如果您需要更改如何处理响应,则可以使用map指令根据响应标头设置变量,然后在add_header(设置客户端响应标头)、log_format或任何其他在响应阶段(内部命名为NGX_HTTP_CONTENT_PHASENGX_HTTP_LOG_PHASE阶段)处于活动状态的指令中使用这些变量。对于更复杂的控制,您将需要使用脚本附加程序,例如Lua模块(例如使用header_filter_by_lua_block指令)。

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

目标 类型 读取(变量) 写入(指令)
客户端 nginx 请求 $http_name
ngnix 上游服务器 请求 proxy_set_header
上游服务器 nginx 响应 $upstream_http_name
nginx 客户端 响应 $sent_http_name add_header

NGINX使用各种proxy_指令将某些客户端请求头复制到上游请求中,并将某些上游响应头复制到客户端响应中,使您可以选择省略或明确包含任一方向的头。因此,如果在$upstream_http_name变量中仅找到上游响应头,则这些头明确未复制到客户端响应中,并且可用的$sent_http_name变量集将包括NGINX设置的任何额外头,这些头不在上游响应中。


63
我遇到了相同的问题。我尝试了$http_my_custom_header$sent_http_my_custom_header,但对我没有用。
虽然我通过使用$upstream_http_my_custom_header解决了这个问题。

1
适当的变量$upstream_http_name模式在此处有文档记录:http://nginx.org/en/docs/http/ngx_http_upstream_module.html#variables - AdamKalisz

11

使用 $http_MY_CUSTOM_HEADER

您可以编写类似以下内容的东西

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

13
男性说 - 变量名的最后一部分是字段名称转换为 __小写字母__,将破折号替换为下划线。 - Arjun Sreedharan

0

当我尝试在nginx配置中访问时,无法提供自定义头部mobile_appif($http_mobile_app = '0') 找不到这个头部,需要将请求头重命名为mobile-app,但我没有找到任何关于它的信息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接