Nginx学习笔记16rewrite之break

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Nginx学习笔记16rewrite之break相关的知识,希望对你有一定的参考价值。

break标志,对目标地址进行请求。break存在时,rewrite的情况比较复杂。

 

nginx匹配成功某个location中的这种类型的rewrite之后,将不再进行其它location的处理,即其它location即使可以匹配rewrite后的目录地址,也不会执行其中的proxy_pass等指令,而是把rewrite后的目标地址作为Nginx本地页面地址直接访问。当rewrite后产生的本地页面地址对应的物理页面存在时,将可以正常访问该页面,否则产生404错误。

 

 

Nginx配置:

 location / {

            root   html;

            index  index.html;

        }

 

        location ~  ^/hello/ {

             proxy_pass  http://tomcat101.coe2coe.me:8080;

             proxy_set_header X-Real-IP  $remote_addr;

             proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

 

            access_log logs/http_hello_access.log  my_access_log;

 

       }

 

      location ~ ^/app/ {

        rewrite ^/app/(.*)$  /hello/$1  break;

     }

 

     location ~ ^/app2/ {

        rewrite ^/app2/(.*)$  /app/$1  break;

     }

 

 

运行结果:

 

(1)访问/app/

这种情况下,只会遇到一个rewrite,一个break

curl -v http://ng.coe2coe.me:8000/app/

* Hostname was NOT found in DNS cache

*   Trying 192.168.197.101...

* Connected to ng.coe2coe.me (192.168.197.101) port 8000 (#0)

> GET /app/ HTTP/1.1

> User-Agent: curl/7.35.0

> Host: ng.coe2coe.me:8000

> Accept: */*

>

< HTTP/1.1 404 Not Found

* Server nginx/1.11.8 is not blacklisted

< Server: nginx/1.11.8

< Date: Sun, 09 Jul 2017 11:12:38 GMT

< Content-Type: text/html

< Content-Length: 169

< Connection: keep-alive

<

<html>

<head><title>404 Not Found</title></head>

<body bgcolor="white">

<center><h1>404 Not Found</h1></center>

<hr><center>nginx/1.11.8</center>

</body>

</html>

* Connection #0 to host ng.coe2coe.me left intact

 

 

http_error.log错误日志:

2017/07/09 19:12:38 [notice] 3194#0: *85 "^/app/(.*)$" matches "/app/", client: 192.168.197.101, server: ng.coe2coe.me, request: "GET /app/ HTTP/1.1", host: "ng.coe2coe.me:8000"

2017/07/09 19:12:38 [notice] 3194#0: *85 rewritten data: "/hello/", args: "", client: 192.168.197.101, server: ng.coe2coe.me, request: "GET /app/ HTTP/1.1", host: "ng.coe2coe.me:8000"

2017/07/09 19:12:38 [error] 3194#0: *85 "/opt/nginx/html/hello/index.html" is not found (2: No such file or directory), client: 192.168.197.101, server: ng.coe2coe.me, request: "GET /app/ HTTP/1.1", host: "ng.coe2coe.me:8000"

2017/07/09 19:12:38 [info] 3194#0: *85 client 192.168.197.101 closed keepalive connection

 

 

由于处理/app/中的rewrite时,取得匹配后的URL/hello/后,遇到了break标志,将不再对/hello/进行其它location进行匹配,此时将直接访问/opt/nginx/html/hello/index.html,但是该文件并不存在,因此出现404错误。在配置文件中存在可以匹配/hello/location,但是在有break标志的情况下,并不会再继续去匹配这个location

 

 

(2)访问/app2/

/app2/location都有匹配的待break标志的rewrite语句,将会执行这个rewrite语句,Nginx维护的目标地址由/app2/变化为/app/。此时试图访问/opt/nginx/html/app/index.html,如果该文件存在,则Nginx继续匹配/app/location中的rewrite语句。此时的执行结果如下所示:

 

curl -v http://ng.coe2coe.me:8000/app2/

* Hostname was NOT found in DNS cache

*   Trying 192.168.197.101...

* Connected to ng.coe2coe.me (192.168.197.101) port 8000 (#0)

> GET /app2/ HTTP/1.1

> User-Agent: curl/7.35.0

> Host: ng.coe2coe.me:8000

> Accept: */*

>

< HTTP/1.1 404 Not Found

* Server nginx/1.11.8 is not blacklisted

< Server: nginx/1.11.8

< Date: Sun, 09 Jul 2017 11:20:22 GMT

< Content-Type: text/html

< Content-Length: 169

< Connection: keep-alive

<

<html>

<head><title>404 Not Found</title></head>

<body bgcolor="white">

<center><h1>404 Not Found</h1></center>

<hr><center>nginx/1.11.8</center>

</body>

</html>

* Connection #0 to host ng.coe2coe.me left intact

 

 

http_error.log错误日志:

2017/07/09 19:20:22 [notice] 3194#0: *86 "^/app2/(.*)$" matches "/app2/", client: 192.168.197.101, server: ng.coe2coe.me, request: "GET /app2/ HTTP/1.1", host: "ng.coe2coe.me:8000"

2017/07/09 19:20:22 [notice] 3194#0: *86 rewritten data: "/app/", args: "", client: 192.168.197.101, server: ng.coe2coe.me, request: "GET /app2/ HTTP/1.1", host: "ng.coe2coe.me:8000"

2017/07/09 19:20:22 [notice] 3194#0: *86 "^/app/(.*)$" matches "/app/index.html", client: 192.168.197.101, server: ng.coe2coe.me, request: "GET /app2/ HTTP/1.1", host: "ng.coe2coe.me:8000"

2017/07/09 19:20:22 [notice] 3194#0: *86 rewritten data: "/hello/index.html", args: "", client: 192.168.197.101, server: ng.coe2coe.me, request: "GET /app2/ HTTP/1.1", host: "ng.coe2coe.me:8000"

2017/07/09 19:20:22 [error] 3194#0: *86 open() "/opt/nginx/html/hello/index.html" failed (2: No such file or directory), client: 192.168.197.101, server: ng.coe2coe.me, request: "GET /app2/ HTTP/1.1", host: "ng.coe2coe.me:8000"

2017/07/09 19:20:22 [info] 3194#0: *86 client 192.168.197.101 closed keepalive connection

 

这种情况下,Nginx访问路径依次为/app2//app//hello/index.html。由于/hello/index.html不存在对应的本地页面,所以出现404错误。由curl的输出结果可以看到,curl看到的是/app2/的状态为404,而并非/hell/index.html。用浏览器访问/app2/时,在这里出现404错误时,可以观察到地址栏的URL并无变化。

 技术分享

 

 

如果/opt/nginx/html/app/index.html文件不存在,而且app目录也不存在,则curl或浏览器获取到的404错误信息没有变化,但是Nginx的错误日志http_error.log中的错误信息有很大变化。此时可以看到是因为没有找到/opt/nginx/html/app/index.html文件而出错,跟/hello/没有任何关系。

 

http_error.log错误日志:

2017/07/09 19:57:18 [notice] 3715#0: *95 "^/app2/(.*)$" matches "/app2/", client: 192.168.197.101, server: ng.coe2coe.me, request: "GET /app2/ HTTP/1.1", host: "ng.coe2coe.me:8000"

2017/07/09 19:57:18 [notice] 3715#0: *95 rewritten data: "/app/", args: "", client: 192.168.197.101, server: ng.coe2coe.me, request: "GET /app2/ HTTP/1.1", host: "ng.coe2coe.me:8000"

2017/07/09 19:57:18 [error] 3715#0: *95 "/opt/nginx/html/app/index.html" is not found (2: No such file or directory), client: 192.168.197.101, server: ng.coe2coe.me, request: "GET /app2/ HTTP/1.1", host: "ng.coe2coe.me:8000"

2017/07/09 19:57:18 [info] 3715#0: *95 client 192.168.197.101 closed keepalive connection

 

 

如果/opt/nginx/html/app/目录存在,但是该目录中并不存在默认的首页文件index.html,则出现403拒绝访问错误。

curl -v http://ng.coe2coe.me:8000/app2/

* Hostname was NOT found in DNS cache

*   Trying 192.168.197.101...

* Connected to ng.coe2coe.me (192.168.197.101) port 8000 (#0)

> GET /app2/ HTTP/1.1

> User-Agent: curl/7.35.0

> Host: ng.coe2coe.me:8000

> Accept: */*

>

< HTTP/1.1 403 Forbidden

* Server nginx/1.11.8 is not blacklisted

< Server: nginx/1.11.8

< Date: Sun, 09 Jul 2017 11:59:30 GMT

< Content-Type: text/html

< Content-Length: 169

< Connection: keep-alive

<

<html>

<head><title>403 Forbidden</title></head>

<body bgcolor="white">

<center><h1>403 Forbidden</h1></center>

<hr><center>nginx/1.11.8</center>

</body>

</html>

* Connection #0 to host ng.coe2coe.me left intact

 

http_error.log错误日志:

2017/07/09 19:59:30 [notice] 3715#0: *96 "^/app2/(.*)$" matches "/app2/", client: 192.168.197.101, server: ng.coe2coe.me, request: "GET /app2/ HTTP/1.1", host: "ng.coe2coe.me:8000"

2017/07/09 19:59:30 [notice] 3715#0: *96 rewritten data: "/app/", args: "", client: 192.168.197.101, server: ng.coe2coe.me, request: "GET /app2/ HTTP/1.1", host: "ng.coe2coe.me:8000"

2017/07/09 19:59:30 [error] 3715#0: *96 directory index of "/opt/nginx/html/app/" is forbidden, client: 192.168.197.101, server: ng.coe2coe.me, request: "GET /app2/ HTTP/1.1", host: "ng.coe2coe.me:8000"

2017/07/09 19:59:30 [info] 3715#0: *96 client 192.168.197.101 closed keepalive connection

 

本文小结:

使用了break标志之后的rewrite语句,会导致不再匹配其它的location,但是如果能够匹配目标地址的location中有可以匹配的rewrite语句的,仍然会执行这些rewrite语句。

以上是关于Nginx学习笔记16rewrite之break的主要内容,如果未能解决你的问题,请参考以下文章

Nginx笔记之Rewrite规则

Nginx学习笔记14rewrite之permanent永久重定向

Nginx学习笔记15rewrite之redirect临时重定向

Nginx之rewrite使用

nginx rewrite的break与last区别 小记

怎样区别nginx中rewrite时break和last