nginx 的 proxy 模块使我们经常会用到的模块之一,比如我们常用的 nginx 反向代理。

反向代理我们一般有这么几行配置代码:

  1. location /api {
  2. proxy_pass http://127.0.0.1:9090;
  3. proxy_set_header Host $host;
  4. ...
  5. }

proxy_pass 是反向代理的目的地址,是比较熟悉的,但第三行是什么意思呢?

proxy_set_header

这个配置是允许你代理后修改请求头的各个字段,可支持 nginx 内置变量、字符串和两种组合方式。

Host

这次要详细理解的是 Host 的几种配置:

  1. proxy_set_header Host $proxy_host
  2. proxy_set_header Host $http_host
  3. proxy_set_header Host $host

测试流程:

  1. postman发送请求nginx服务127.0.0.1:4000;
  2. nginx中转后node服务127.0.0.1:9090;
  3. node服务打印request.host看看是什么。

$proxy_host

默认值(不配置等同于配置了 proxy_set_header Host $proxy_host),nginx 配置:

  1. location /api {
  2. proxy_pass http://127.0.0.1:9090;
  3. }
  4. location /api {
  5. proxy_pass http://127.0.0.1:9090;
  6. proxy_set_header Host $proxy_host
  7. }

代理后的请求头的 Host : 127.0.0.1:9090 ,所以$proxy_host 为 proxy_pass 中的域名
**

$http_host

nginx 配置:

  1. location /api {
  2. proxy_pass http://127.0.0.1:9090;
  3. proxy_set_header Host $http_host;
  4. }

postman 另外配置头部中的 Host:
image.png
代理后的请求头的 Host : www.baidu.com ,所以$http_host 为代理前的请求头的 Host。
**

$host

$host 根据文档介绍,如果请求头有 Host 字段会取该字段,否则就会去主服务器名(也就是 server_name )。

首先和 $http_host 一样,自定义 Host,得到的和 $http_host 是一致的,证明了前半句。

接着是传一个空的 Host,但实际上是不可行的,根据 HTTP/1.1 开规定,如果 Host 为空,会返回 400(如下图),nginx 也很好地实现了这个规定。

image.png
而HTTP/1.0是允许的,这里猜测是该字段为了HTTP/1.0设计的。

结论

以上就是三种配置的差别,一般常用proxy_set_header Host $host