proxy_set_header官网说明

官网关于proxy_set_header的说明如下:

Syntax:   proxy_set_header field value;
Default:  proxy_set_header Host $proxy_host;
          proxy_set_header Connection close;
Context:  httpserverlocation

Allows redefining or appending fields to the request header passed to the proxied server. The value can contain text, variables, and their combinations. These directives are inherited from the previous level if and only if there are no proxy_set_header directives defined on the current level. By default, only two fields are redefined:

proxy_set_header Host       $proxy_host;
proxy_set_header Connection close;

If caching is enabled, the header fields “If-Modified-Since”, “If-Unmodified-Since”, “If-None-Match”, “If-Match”, “Range”, and “If-Range” from the original request are not passed to the proxied server.

An unchanged “Host” request header field can be passed like this:

proxy_set_header Host       $http_host;

However, if this field is not present in a client request header then nothing will be passed. In such a case it is better to use the $host variable – its value equals the server name in the “Host” request header field or the primary server name if this field is not present:

proxy_set_header Host       $host;

In addition, the server name can be passed together with the port of the proxied server:

proxy_set_header Host       $host:$proxy_port;

f the value of a header field is an empty string then this field will not be passed to a proxied server:

proxy_set_header Accept-Encoding "";
几个需要注意的地方:
  • $host、$proxy_host和$http_host区别
  • Http协议header头中的host对Nginx的影响

$host、$proxy_host和$http_host区别

为了更方便的说明这三者之间的区别,我们使用一个转发范例进行说明:

    upstream myapp1 {
        server app.example.com;
    }

    server {
        listen 80;
        server_name  proxy1.test.com;
        location / {
            proxy_pass http://myapp1;
            proxy_set_header Host $host;
        }
    }

    server {
        listen 80;
        server_name  proxy2.test.com;
        location / {
            proxy_pass http://myapp1;
            proxy_set_header Host $proxy_host;
        }
    }

   server {
        listen 80;
        server_name  proxy3.test.com;
        location / {
            proxy_pass http://myapp1;
            proxy_set_header Host $http_host;
        }
    }
  • $host 按照如下优先级获得
    • 请求行中的host
    • 请求头中的Host头部
    • 与一条请求匹配的server name
  • $proxy_host 默认值,即代理的和转发的host
  • $http_host 请求头中读取到的Host

范例1:

curl -X GET \
  http://proxy1.test.com/ \
  -H 'Accept: */*' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Host: proxy1.test.com' \
  -H 'Referer: http://proxy1.test.com/' \
  -H 'cache-control: no-cache'

此时$host的值为proxy1.test.com

范例2:

curl -X GET \
  http://proxy2.test.com/ \
  -H 'Accept: */*' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Host: proxy2.test.com' \
  -H 'Referer: http://proxy1.test.com/' \
  -H 'cache-control: no-cache'

此时$proxy_host的值为app.example.com

范例2:

curl -X GET \
  http://proxy3.test.com/ \
  -H 'Accept: */*' \
  -H 'Accept-Encoding: gzip, deflate' \
  -H 'Cache-Control: no-cache' \
  -H 'Connection: keep-alive' \
  -H 'Host: proxy3.test.com' \
  -H 'Referer: http://proxy1.test.com/' \
  -H 'cache-control: no-cache'

此时$http_host的值为proxy3.test.com

header头中的Host对Nginx代理的影响

Nginx在做代理服务时,通常会启用多个server,请求会根据server name,进入相应的server配置执行流程,而Host就是Nginx进入不同server执行流程的依据,因此,在多server name的配置中,Host的正确至关重要,也要求我们在构建Http请求时,一定规范的使用Host这个header头。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

Post Navigation