# proxy\_pass

<mark style="color:blue;">**proxy\_pass**</mark>指令用来<mark style="color:blue;">**设置被代理服务器的地址，可以是主机名称、IP地址加端口号等形式**</mark>。其语法结构为：

```nginx
proxy_pass URL;
```

其中，<mark style="color:blue;">**URL**</mark>为**要设置的被代理服务器的地址，包含传输协议、主机名称或IP地址加端口号、**<mark style="color:orange;">**URI**</mark>**等要素**。传输协议通常是“http”或者“https”，同时还接受以“unix”开始的UNIX-domain套接字路径。例如：

```nginx
proxy_pass http://www.myweb.name/uri;
proxy_pass http://localhost:8000/uri/;
proxy_pass http://unix:/tmp/backend.socket:/uri/;
```

## upstream

**如果被代理服务器是一组服务器的话，可以使用**<mark style="color:blue;">**upstream**</mark>**指令配置后端服务器组**。例如：

```nginx
…
upstream proxy_svrs                                              #配置后端服务器组
{
  server http://192.168.1.1:8001/uri/;
  server http://192.168.1.2:8001/uri/;
  server http://192.168.1.3:8001/uri/;
}
server
{
  …
  listen 80;
  server_name  www.myweb.name;
  location /
  {
    proxy_pass  proxy_svrs;                                       #使用服务器组的名称
  }
}
```

在上例中，**在组内的各个服务器中都指明了传输协议“http\://”，而在proxy\_pass指令中就不再需要指明了**。如果现在将upstream指令的配置改为：

```nginx
upstream proxy_svrs
{
  server 192.168.1.1:8001/uri/;
  server 192.168.1.2:8001/uri/;
  server 192.168.1.3:8001/uri/;
}
```

我们就需要在proxy\_pass指令中指明传输协议“http\://”：

```nginx
proxy_pass  http://proxy_svrs;
```

## **URL中是否包含有URI，Nginx服务器的处理方式是不同的**

在使用该指令的过程中要注意，**URL中是否包含有URI，Nginx服务器的处理方式是不同的**。

* <mark style="color:orange;">**如果URL中不包含URI，Nginx服务器不会改变原地址的URI**</mark>；
* 但是<mark style="color:orange;">**如果包含了URI，Nginx服务器将会使用新的URI替代原来的URI**</mark>。

```nginx
…
server
{
  …
  listen 80;
  server_name  www.myweb.name;
  location  /server/
  {
    …
    proxy_pass  http://192.168.1.1;
  }
}
```

在上面的Nginx配置片段中，如果客户端使用“\*\*<http://www.myweb.name/server**”发起请求，该请求被配置中显示的location块进行处理，**由于proxy\\_pass指令的URL变量不含有URI**，所以转向的地址为“**http://192.168.1.1/server**”。>

再来看下面的Nginx配置片段：

```nginx
…
server
{
  …
  listen 80;
  server_name  www.myweb.name;
  location /server/
  {
    …
    proxy_pass  http://192.168.1.1/loc/;
  }
}
```

在该配置实例中，**proxy\_pass指令的URL包含了URI“/loc/”**。如果客户端仍然使用“**<http://www>. myweb.name/server/**”发起请求，Nginx服务器将会把地址转向“\*\*<http://192.168.1.1/loc/**”。>

通过上面的实例，可以总结出，<mark style="color:orange;">**在使用proxy\_pass指令时，如果不想改变原地址中的URI，就不要在URL变量中配置URI。**</mark>

{% hint style="success" %}

```nginx
…
server
{
  …
  listen 80;
  server_name  www.myweb.name;
  location  /                                #注意location的uri变量
  {
    …
    #配置1：  proxy_pass  http://192.168.1.1;
    #配置2：  proxy_pass  http://192.168.1.1/;
  }
}
```

**在该配置中，location块使用“/”作为uri变量的值来匹配不包含URI的请求URL。由于请求URL中不包含URI，因此配置1和配置2的效果是一样的**。

比如，客户端的请求URL为“<http://www.myweb.name/index.htm”，其将会被实例1中的location块匹配成功并进行处理。不管使用配置1还是配置2，转向的URL都为：“http://192.168.1.1/index.htm”。>

```nginx
…
server
{
  …
  listen 80;
  server_name  www.myweb.name;
  location  /server/                          #注意location的uri变量
  {
    …
    #配置1：  proxy_pass  http://192.168.1.1;
    #配置2：  proxy_pass  http://192.168.1.1/;
  }
}
```

**在该配置中，location块使用“/server/”作为uri变量的值来匹配包含URI “/server/” 的请求URL。**&#x8FD9;时，使用配置1和配置2的转向结果就不相同了。

* 使用配置1的时候，proxy\_pass指令中的URL变量不包含URI，Nginx服务器将不改变原地址的URI；
* 使用配置2的时候，proxy\_pass指令中的URL变量包含URI “/”，Nginx服务器会将原地址的URI替换为“/”。

比如，客户端的请求URL为“<http://www.myweb.name/server/index.htm”，将会被配置中的location块匹配成功并进行处理。>

* <mark style="color:orange;">**使用配置1的时候，转向的URL为“<http://192.168.1.1/server/index.htm”，原地址的URI> “/server/”未被改变；**</mark>
* <mark style="color:orange;">**但使用配置2时，转向的URL为“<http://192.168.1.1/index.htm”，可以看到，原地址的URI> “/server/”被替换为“/”。**</mark>
  {% endhint %}
