nginx location深入解析
nginx中location块定义文件路径的配置
nginx在接收到客户端请求时,会通过查找配置文件将客户端的请求映射到location block,location中所配置的每个配置项会启动不同的模块去相应请求。
默认ngxin.conf中至少存在一个location /,即客户端浏览器的请求为 http://域名+/ 。
如果location /newindex/ 即表示客户端浏览器的请求为:http://域名+/newindex/ 。
location匹配方式,location匹配的优先级,与其在配置文件中先后顺序无关。
location 匹配方式
#普通匹配 = 精准匹配 ^~ 最大前缀匹配 / 不带任何前缀:最大前缀匹配
#正则表达式匹配
~ 大小写相关匹配 ~* 大小写无关匹配 @ location内部的重定向变量
优先级如下
( location = ) > ( location 完整路径 ) > ( location ^~ 前缀匹配 ) > ( location ~|~* 正则匹配顺序 ) > ( location部分起始路径 ) > ( location / )
( location = )匹配方式
如下配置测试,可以看到如下黄体红字的部分,使用了( location = ) 匹配方式,这个优先级大于 ( location / ),那么我们请求http://localhost:80/ 或http://localhost:80/index.html时,就看到这个返回的是<prefix>/html/test1/index.html文件
server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } location = /index.html { root html/test1; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
测试返回结果如下:
[root@node1 conf]# curl http://localhost:80/ this is test localtion /index.html [root@node1 conf]# cat /usr/pkgs/nginx/html/test1/index.html this is test localtion /index.html [root@node1 conf]#
( location 完整y页面路径 ) 匹配方法
有的时候为了防止冲突我们需要使用完整路径的匹配。
我们在nginx.conf中server块中,加入如下location块(黄体红字部分)。然后访问http://localhost:80/test2/index.html可以看到 访问了<prefix>/html/test2/index.html文件。
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } # block1: test localtion = directory location = /index.html { root html/test1; } # block 2: test localtion detail directory location test2/index.html { root html/test2; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
测试结果如下;
#默认<prefix>/html/index.html页面 [root@node1 nginx]# cat html/index.html |head -10 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } #block2 ( location 具体路径 )模式的页面 [root@node1 nginx]# cat html/test2/index.html this is test localtion /test2/index.html #block1 ( location = 路径) 模式的页面 [root@node1 nginx]# cat html/test1/index.html this is test localtion /index.html [root@node1 nginx]# #匹配block 1 (location = 路径)模式 # 访问默认的index.html返回 html/test1/index.html [root@node1 conf]# curl http://localhost:80/ this is test localtion /index.html #匹配block 1 (location = 路径)模式 # 访问默认的localhost:80/index.html返回 html/test1/index.html [root@node1 conf]# curl http://localhost:80/index.html this is test localtion /index.html #匹配block 2 (location = 具体路径) # 访问的localhost:80/test2/index.html返回 html/test2/index.html [root@node1 conf]# curl http://localhost:80/test2/index.html this is test localtion /test2/index.html
如果在 location test2/index.html 做一些修改改为 location /test2/index.html 匹配目录,那么就会报错。注意到 ( location /test2/index.html) 和( location test2/index.html )的区别。前者以 / 起始。
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } # test localtion detail directory location /test2/index.html { root html/test2; } # test localtion detail directory location test2/index.html { root html/test2; } # test localtion = directory location = /index.html { root html/test1; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
[root@node1 nginx]# curl http://localhost:80/test2/index.html <html> <head><title>404 Not Found</title></head> <body> <center><h1>404 Not Found</h1></center> <hr><center>nginx/1.20.2</center> </body> </html>
如果location 后面以/起始 例如 ( location /test1/)那么表示location匹配的是路径,我们需要在root下面创建好必须的文件。
[root@node1 nginx]# cat html/test2/test2/index.html test location /test2/index.html root html test2;<br/> directory : <prefix>/html/test2/test2/index.html [root@node1 nginx]# curl http://localhost/test2/index.html test location /test2/index.html root html test2;<br/> directory : <prefix>/html/test2/test2/index.html [root@node1 nginx]#
对比( location /test ) , ( location /test/ ) , ( location /test/ alias ) ,( location /test alias ) ,(location test/ root),(location test/index.html),(location test/noindex.html)的区别
worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } # test alias with /test1/ location /test1/ { alias html; } # test alias with /test2 location /test2 { alias html; } #test root with /test3/ location /test3/ { root html; } #test root with /test4 location /test4 { root html; } #test root with test5 location test5/ { root html; } #test root with test5/index.html location test5/index.html { root html; } #test root with test5/noindex.html location test5/noindex.html { root html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } } }
结果如下
#使用alias时 末尾不能带/,否则会报错403 [root@node1 nginx]# curl http://localhost/test1/ <html> <head><title>403 Forbidden</title></head> <body> <center><h1>403 Forbidden</h1></center> <hr><center>nginx/1.20.2</center> </body> </html> #使用alias时 访问http://localhost/test2必须要加/否则会报错 [root@node1 nginx]# curl http://localhost/test2 <html> <head><title>301 Moved Permanently</title></head> <body> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx/1.20.2</center> </body> </html> #使用alias 末尾没有/没有报错,只是一个alias和不加test2一样 [root@node1 nginx]# curl http://localhost/test2/ <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> #location /test3/ 匹配目录时末尾可以加/不会报错。需要有html/test3/index.html [root@node1 nginx]# curl http://localhost/test3/ test localtion /test3/ ; root html; #location /test4 匹配目录时末尾可以不加/不会报错。需要有html/test4/index.html [root@node1 nginx]# curl http://localhost/test4/ test localtion /test4 ; root html; #location test5/ 不完全匹配,可以不加/index.html [root@node1 nginx]# curl http://localhost/test5/ test location test5/index.html ; root html; [root@node1 nginx]# curl http://localhost/test6/ <html> <head><title>404 Not Found</title></head> <body> <center><h1>404 Not Found</h1></center> <hr><center>nginx/1.20.2</center> </body> </html> # location test5/index.html完整匹配 [root@node1 nginx]# curl http://localhost/test5/index.html test location test5/index.html ; root html; # location test5/noindex.html 完整匹配 [root@node1 nginx]# curl http://localhost/test5/noindex.html test location test5/noindex.html ; root html; [root@node1 nginx]#
测试不完整匹配,location test6。 如果有html/test6 和有html/test6/index.html的情况会选哪个。
[root@node1 nginx]# cat conf/nginx.conf worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name localhost; location / { root html; index index.html index.htm; } #test root with test6 location test6 { root html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root html; } }
测试结果如下
#html/test6文件存在 [root@node1 nginx]# cat html/test6 test location test6; root html <br/> html/test6
#http://localhost/test6正常访问 [root@node1 html]# curl http://localhost:/test6 test location test6; root html <br/> html/test6
#http://localhost/test6/无法访问 [root@node1 nginx]# curl http://localhost/test6/ <html> <head><title>404 Not Found</title></head> <body> <center><h1>404 Not Found</h1></center> <hr><center>nginx/1.20.2</center> </body> </html> #当html/test6不存在,而html/test6/index.html文件存在 [root@node1 nginx]# cat html/test6/index.html test location test6; root html; <br/> html/test6/index.html #http://localhost/test6无法访问 [root@node1 nginx]# curl http://localhost:/test6 <html> <head><title>301 Moved Permanently</title></head> <body> <center><h1>301 Moved Permanently</h1></center> <hr><center>nginx/1.20.2</center> </body> </html>
#http://localhost/test6/可以访问 [root@node1 nginx]# curl http://localhost:/test6/ test location test6; root html; <br/> html/test6/index.html