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学习笔记14rewrite之permanent永久重定向