Nginx处理请求时的匹配规则详析

  

nginx在收到一条请求时将先通过server_name匹配一个服务器,然后使用服务器中位置的继续匹配。
  

  


  

  

在nginx中,server_name决定了当收到一个请求后哪一个服务器会被使用。nginx会使用请求头中字的主机段与server_name进行匹配。定义server_name时可以使用完全名称,通配符名称,正则表达式名称,它们的匹配顺序如下:

  
      <李>完全匹配李   <李>前通配符匹配,即* .example.org   <李>后通配符匹配,即邮件。*   <李>正则表达式匹配李   
  

如果没有匹配到结果,将会使用default_server进行处理,如果没有定义,则第一个定义的为default_server。使用三个简单的服务器作为例子,让他们监听80端口,server_name分别设置为.org * * . net, * . com:
  

        服务器{   听80;   server_name example.org www.example.org;   返回401;   }      服务器{   听80;   server_name example.net www.example.net;   返回402;   }      服务器{   听80;   server_name example.com www.example.com;   返回403;   }      

在上面的配置中,默认的服务器为第一个,随便访问一个不存在的服务器将会返回401。不过可以使用default_server手动设置一个默认主机,default_server设置在听字段,如下:
  

        服务器{   听80 default_server;   server_name example.net www.example.net;   }      

之后再匹配时,未匹配到将会使用这个服务器。
  

  


  

  

如果想要禁止一个没有携带主机字段的请求,可以定义如下服务器:
  

        服务器{   听80;   server_name”;   返回444;   }      

server_name定义为空字符串,如果主机字段为空或不存在,将会匹配到这个服务器,然后返回404状态码。

  
  444年

Nginx的状态比较特殊,如果返回444那么客户端将不会收到服务端返回的信息,就像是网站无法连接一样,浏览器直接显示502。但是如果使用反向代理,还是显示正常状态码

     

如果想要禁止访问不存在的主机,可以这样定义:
  

        服务器{   听80 default_server;   server_name _;   返回444;   }      

_在这里没有任何特别含义,因为一个域名中不会出现_,所以不会与任何真实的域名相同,使用其他非法字符是相同的道理。
  

  


  

  

现在来看一下对于监听不同IP和不同server_name混合使用时是如何处理的:
  

        服务器{   听192.168.1.1:80;   server_name example.org www.example.org;   }      服务器{   听192.168.1.1:80;   server_name example.net www.example.net;   }      服务器{   听192.168.1.2:80;   server_name example.com www.example.com;   }      

在这个配置中,nginx首先匹配的IP,匹配到后再匹配它们的server_name,如果没有匹配到server_name,则使用到它们默认的服务器。举个例子,如果一个域名为www.example.com的请求来自192.168.1.1:80。但是监听192.168.1.1:80的服务器只有两个,这两个都不能匹配www.example.com,那么就使用这两个服务器中的默认主机,由于没有使用defualt_server定义监听,所以默认为第一个即www.example.org这个服务器。当然你可以定义defualt_server:
  

        服务器{   听192.168.1.1:80;   server_name example.org www.example.org;   }      服务器{   听192.168.1.1:80 default_server;   server_name example.net www.example.net;   }      服务器{   听192.168.1.2:80 default_server;   server_name example.com www.example.com;   }      


  

  

在nginx匹配到一个服务器后,就会通过位置继续处理请求,下面是一个示例:
  

        服务器{   听172.17.0.3:80;   server_name _;      位置/{   返回401;   }      ~ * \位置。(gif | jpg | png) $ {   返回402;   }      ~ * \位置。(gif | jpg | png) $ {   返回404;   }      位置/api {   返回403;   }   }      

nginx首先会在所有的位置中搜索前缀进行匹配,匹配到前缀后,将按顺序匹配使用正则表达式定义的位置,匹配到就结束,如果没有匹配到,则使用之前匹配到前缀的那个位置进行处理,下面是具体匹配的例子:

Nginx处理请求时的匹配规则详析