# How Nginx Decides Which Server Block Will Handle a Request post=>theresia emt|December 24, 2020|4295|316|https://lh3.googleusercontent.com/a-/AOh14GhPb7zfSSYTvNA6psX28gfeiA5br7m1iPhwq72_-Q=s96-c tags=>nginx > Respect to [Understanding Nginx Server and Location Block Selection Algorithms](https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms#:~:text=First%2C%20Nginx%20looks%20at%20the,server%20block%20will%20respond%20to.) ## Parsing the “server_name” Directive to Choose a Match Next, to further evaluate requests that have equally specific listen directives, Nginx checks the request’s “Host” header. This value holds the domain or IP address that the client was actually trying to reach. ## Matching Location Blocks Similar to the process that Nginx uses to select the server block that will process a request, Nginx also has an established algorithm for deciding which location block within the server to use for handling requests. ### Location Block Syntax Location blocks generally take the following form: ``` location optional_modifier location_match { . . . } ``` The modifiers below will cause the associated location block to be interpreted as follows: + `(none)`: If no modifiers are present, the location is interpreted as a prefix match. This means that the location given will be matched against the beginning of the request URI to determine a match. + `=`: If an equal sign is used, this block will be considered a match if the request URI exactly matches the location given. = 开头表示精确匹配,只有完全匹配上才能生效 + `~`: If a tilde modifier is present, this location will be interpreted as a case-sensitive regular expression match. ~ 开头表示区分大小写的正则匹配 + `~*`: If a tilde and asterisk modifier is used, the location block will be interpreted as a case-insensitive regular expression match. ~* 开头表示不区分大小写的正则匹配 + `^~`: If a carat and tilde modifier is present, and if this block is selected as the best non-regular expression match, regular expression matching will not take place. ^~ 开头对URL路径进行前缀匹配,并且在正则之前。 + `/uri`: 不带任何修饰符,也表示前缀匹配,但是在正则匹配之后 + `/`: 通用匹配,任何未匹配到其它location的请求都会匹配到,相当于switch中的default ### When Does Location Block Evaluation Jump to Other Locations? Another instance where the processing location may be reevaluated is with the try_files directive. This directive tells Nginx to check for the existence of a named set of files or directories. The last parameter can be a URI that Nginx will make an internal redirect to. Consider the following configuration: ``` root /var/www/main; location / { try_files $uri $uri.html $uri/ /fallback/index.html; } location /fallback { root /var/www/another; } ``` ### proxy_pass反向代理配置中url后面加不加/的说明 #### path 后面加 / ``` location /proxy/ { proxy_pass http://192.168.1.5:8090/; } 这样,访问http://192.168.1.23/proxy/就会被代理到http://192.168.1.5:8090/。p匹配的proxy目录不需要存在根目录/var/www/html里面 注意,终端里如果访问http://192.168.1.23/proxy(即后面不带"/"),则会访问失败!因为proxy_pass配置的url后面加了"/" 浏览器访问http://103.110.186.23/proxy的时候,会自动加上"/”(同理是由于proxy_pass配置的url后面加了"/"),并反代到http://103.110.186.5:8090的结果 ``` ``` location /proxy/ { proxy_pass http://192.168.1.5:8090; } 那么访问http://192.168.1.23/proxy或http://192.168.1.23/proxy/,都会失败! 这样配置后,访问http://192.168.1.23/proxy/就会被反向代理到http://192.168.1.5:8090/proxy/ ``` ``` location /proxy/ { proxy_pass http://192.168.1.5:8090/haha/; } 这样配置的话,访问http://103.110.186.23/proxy/代理到http://192.168.1.5:8090/haha/ ``` ``` location /proxy/ { proxy_pass http://192.168.1.5:8090/haha; } 上面配置后,访问http://192.168.1.23/proxy/index.html就会被代理到http://192.168.1.5:8090/hahaindex.html 同理,访问http://192.168.1.23/proxy/test.html就会被代理到http://192.168.1.5:8090/hahatest.html 注意,这种情况下,不能直接访问http://192.168.1.23/proxy/,后面就算是默认的index.html文件也要跟上,否则访问失败! ``` #### path路径后面不带 / ``` location /proxy { proxy_pass http://192.168.1.5:8090/; } ``` ``` location /proxy { proxy_pass http://192.168.1.5:8090; } 这样配置的话,浏览器访问http://103.110.186.23/proxy会自动加上"/”(即变成http://103.110.186.23/proxy/),代理到192.168.1.5:8090/proxy/ ``` ``` location /proxy { proxy_pass http://192.168.1.5:8090/haha/; } 这样配置的话,浏览器访问http://103.110.186.23/proxy会自动加上"/”(即变成http://103.110.186.23/proxy/),代理到http://192.168.1.5:8090/haha/ ``` ``` location /proxy { proxy_pass http://192.168.1.5:8090/haha; } 这样配置的话,浏览器访问http://103.110.186.23/proxy,和第三种结果一样,同样被代理到http://192.168.1.5:8090/haha/ ```