Nginx之localtion规则与地址重写(超详细实例篇)

1.1 location规则介绍

location是nginx的精华,nginx就是通过拦截到的请求去对配置好的location块(location block)进行
请求代理的。
location是用来具体配置代理路径的,具体格式如下:

location [=|~|~*|^~|@] /uri/ {
    
      }

被代理的url去对location后边的字符串(或正则)进行匹配,根据一定的规则选择走哪个location,以
下是匹配规则。

语法规则: location [=|~|~*|^~] /uri/ {
    
      }
= 开头表示精确匹配
^~ 开头表示uri以某个常规字符串开头,理解为匹配 url路径即可。nginx不对url做编码,因此请求
/static/20%/aa,可以被规则^~ /static/ /aa匹配到(注意是空格)。
~ 开头表示区分大小写的正则匹配
~* 开头表示不区分大小写的正则匹配
!~!~*分别为区分大小写不匹配及不区分大小写不匹配 的正则
/ 通用匹配,任何请求都会匹配到
Location优先级:
= > ^~ > ~|~*|!~|!~* > /
相同的优先级,匹配与配置文件的配置顺序有关,在上面的优先匹配

Localtion的匹配规则,首先匹配 =,其次匹配^~, 其次是按文件中顺序的正则匹配,最后是交给 / 通用
匹配。当有匹配成功时候,停止匹配,按当前匹配规则处理请求。

实例:

location = / {
    
    
 #规则A
}
location = /login {
    
    
 #规则B
}
location ^~ /static/ {
    
    
 #规则C
}
location ~ \.(gif|jpg|png|js|css)$ {
    
    
 #规则D
}
location ~* \.png$ {
    
    
 #规则E
}
location !~ \.xhtml$ {
    
    
 #规则F
}
location !~* \.xhtml$ {
    
    
 #规则G
}
location / {
    
    
 #规则H
}

产生效果:

访问根目录/ 比如http://localhost/ 将匹配规则A
访问 http://localhost/login 将匹配规则B,http://localhost/register 则匹配规则H
访问 http://localhost/static/a.html 将匹配规则C
访问 http://localhost/a.gif, http://localhost/b.png 将匹配规则D和规则E,但是规则D顺序
优先,规则E不起作用,而 http://localhost/static/c.png 则优先匹配到 规则C
访问 http://localhost/a.PNG 则匹配规则E, 而不会匹配规则D,因为规则E不区分大小写。
访问http://localhost/a.xhtml 不会匹配规则F和规则G,http://localhost/a.XHT
ML不会匹配规则G,因为不区分大小写。规则F,规则G属于排除法,符合匹配规则但是不会匹配到,所以想想
看实际应用中哪里会用到。
访问 http://localhost/category/id/1111 则最终匹配到规则H,因为以上规则都不匹配,这个时候
应该是nginx转发请求给后端应用服务器,比如FastCGI(php),tomcat(jsp),nginx作为方向代理
服务器存在。

所以实际使用中,通常至少有三个匹配规则定义,如下:

直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,官网如是说。
这里是直接转发给后端应用服务器了,也可以是一个静态首页
第一个必选规则

location = / {
    
    
 proxy_pass http://tomcat:8080/index
}

第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用

location ^~ /static/ {
    
    
 root /webroot/static/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
    
    
 root /webroot/res/;
}

第三个规则就是通用规则,用来转发动态请求到后端应用服务器
非静态文件请求就默认是动态请求,自己根据实际把握
毕竟目前的一些框架的流行,带.php,.jsp后缀的情况很少了

location / {
    
    
 proxy_pass http://tomcat:8080/
}

1.2 地址重写原理与实践

1.2.1 地址重写介绍

Rewrite对称URL Rewrite,即URL重写,就是把传入Web的请求重定向到其他URL的过程。

1.URL Rewrite最常见的应用是URL伪静态化,是将动态页面显示为静态页面方式的一种技术。比如 htt
p://www.123.com/news/index.php?id=123 使用URLRewrite 转换后可以显示为 http://www.123.co
m/news/123.html对于追求完美主义的网站设计师,就算是网页的地址也希望看起来尽量简洁明快。理
论上,搜索引擎更喜欢静态页面形式的网页,搜索引擎对静态页面的评分一般要高于动态页面。所以,
UrlRewrite可以让我们网站的网页更容易被搜索引擎所收录。

2.从安全角度上讲,如果在URL中暴露太多的参数,无疑会造成一定量的信息泄漏,可能会被一些黑客
利用,对你的系统造成一定的破坏,所以静态化的URL地址可以给我们带来更高的安全性。

3.实现网站地址跳转,例如用户访问360buy.com,将其跳转到jd.com。例如当用户访问tianyun.com
的80端口时,将其跳转到443端口。
和apache等web服务软件一样,rewrite的组要功能是实现URL地址的重定向。Nginx的rewrite功能需
要PCRE软件的支持,即通过perl兼容正则表达式语句进行规则匹配的。默认参数编译nginx就会支持
rewrite的模块,但是也必须要PCRE的支持

在这里插入图片描述
rewrite是实现URL重写的关键指令,根据regex(正则表达式)部分内容,重定向到replacement,结
尾是flag标记。

1.2.2 Nginx地址重写语法

在匹配过程中可以引用一些Nginx的全局变量
$args 请求中的参数;
$document_root 针对当前请求的根路径设置值;
$host 请求信息中的"Host",如果请求中没有Host行,则等于设置的服务器名;
$limit_rate 对连接速率的限制;
$request_method 请求的方法,比如"GET""POST";
$remote_addr 客户端地址;
$remote_port 客户端端口号;
$remote_user 客户端用户名,认证用;
$request_filename 当前请求的文件路径名(带root指定的路径)
$request_uri 当前请求的文件路径名(不带root指定的路径 /images/a.jpg)
$query_string 与$args相同;
$scheme 用的协议,比如http或者是https
$server_protocol 请求的协议版本,"HTTP/1.0""HTTP/1.1";
$server_addr 服务器地址,如果没有用listen指明服务器地址,使用这个变量将发起一次系统调用以取得地址;
$server_name 请求到达的服务器名;
$document_uri 与$uri一样,URI地址;
$server_port 请求到达的服务器端口号;

1.2.3 rewrite语法

rewrite语法格式及参数语法说明如下:

rewrite  <regex>  <replacement>  [flag];
关键字     正则      替代内容      flag标记

关键字:其中关键字rewrite不能改变
正则:perl兼容正则表达式语句进行规则匹配
替代内容:将正则匹配的内容替换成replacement
flag标记:rewrite支持的flag标记

flag标记说明:
last #本条规则匹配完成后,继续向下匹配新的location URI规则
break #本条规则匹配完成即终止,不再匹配后面的任何规则
redirect #返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址

区别:
redirect 和 permanent区别则是返回的不同方式的重定向,对于客户端来说一般状态下是没有区别的。而对于搜
索引擎,相对来说301的重定向更加友好,如果我们把一个地址采用301跳转方式跳转的话,搜索引擎会把老地
址的相关信息带到新地址,同时在搜索引擎索引库中彻底废弃掉原先的老地址。使用302重定向时,搜索引擎
(特别是google)有时会查看跳转前后哪个网址更直观,然后决定显示哪个,如果它觉的跳转前的URL更好的话,
也许地址栏不会更改,那么很有可能出现URL劫持的现像。在做URI重写时,有时会发现URI中含有相关参数,
如果需要将这些参数保存下来,并且在重写过程中重新引用,可以用到 () 和 $N 的方式来解决。

1.2.4 rewrite企业应用场景

Nginx的rewrite功能在企业里应用非常广泛:
可以调整用户浏览的URL,看起来更规范,合乎开发及产品人员的需求。
为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态URL地址伪装成静态地址提供服务。
网址换新域名后,让旧的访问跳转到新的域名上。例如,访问京东的360buy.com会跳转到jd.com
根据特殊变量、目录、客户端的信息进行URL调整等

1.2.5 地址重写实例

实例1:如果访问不存在的任意网页都重定向到错误页面

location / {
    
    
     root  html;
     index index.html index.htm;
     if (!-f $request_filename) {
    
    
       rewrite /.* /err.html permanent; (permanent表示永久的重定向到这个页
)
}

实例2:为某个目录定义别名,用户访问的路径其实并不存在,而是将其转发到另外一个页面

location / {
    
    
    root  html;
    index index.html ;
    rewrite ^/forum/(.*) /bbs/$1 last ;
......
}

实例3:实现域名跳转

server {
    
    
   listen    80;
   server_name web.uplook.com;
如果访问web.uplook.com则跳转到www.uplook.com
   rewrite ^/.* http://www.uplook.com/$1 last;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
    
    
   root  html;
   index index.html ;
}

1.2.6 Nginx地址重写企业运用场景

实例一:

#http://www.xingyun.com/abc/a/1.html ==> http://www.xingyun.com/ccc/bbb/2.html
location /abc {
    
    
rewrite .* /ccc/bbb/2.html permanent;
#return 301 /ccc/bbb/2.html;
}

实例二:

#http://www.xingyun.com/2015/ccc/bbb/2.html ==> http://www.xingyun.com/2014/ccc/bbb/2.html
location /2015 {
    
    
rewrite ^/2015/(.*)$ /2014/$1 permanent;
}

实例三:

#http://www.360buy.com/aaa/1.html ==> http://jd.com
if ( $host ~* 360buy.com ) {
    
    
rewrite .* http://jd.com permanent;
}
注意:配置host

实例四:

#http://www.360buy.com/ccc/1.html ==> http://jd.com/ccc/1.html
if ( $host ~* 360buy.com ) {
    
    
rewrite .* http://jd.com$request_uri permanent;
}

实例五:

在访问目录后添加/ (如果目录后已有/,则不加/)
#http://www.xingyun.com/ccc/abc
#$1: /ccc/ab
#$2: c
#http://$host$1$2/
if (-d $request_filename) {
    
    
rewrite ^(.*)([^/])$ http://$host$1$2/ permanent; http://www.360buy123.com/ccc/abc/
}

实例六:

#http://www.xingyun.com/login/xingyun.html ==> http://www.xingyun.com/reg/login.php?user=xingyun
location /login {
    
    
rewrite ^/login/(.*)\.html$ /reg/login.php?user=$1 permanent;
}

实例七:

#http://www.xingyun.com/uplook/11-22-33.html ==> http://www.xingyun.com/uplook/11/22/33.html
location /uplook {
    
    
rewrite ^/uplook/([0-9]+)-([0-9]+)-([0-9]+)\.html$ /uplook/$1/$2/$3.html permanent;
}

实例八:

set 指令是用于定义一个变量,并且赋值。应用于server,location,if环境。
#http://alice.xingyun.com ==> http://www.xingyun.com/alice
#http://jack.xingyun.com ==> http://www.xingyun.com/jack
[root@root html]# mkdir jack alice
[root@root html]# echo jack.... > jack/index.html
[root@root html]# echo alice... > alice/index.html

a. DNS实现泛解析
*.xingyun.com IN A 网站IP
b. nginx Rewrite
if ($host ~* "^www.xingyun.com$" ) {
    
    
break;
}
if ($host ~* "^(.*)\.xingyun\.com$" ) {
    
    
set $user $1;
rewrite .* http://www.xingyun.com/$user permanent;
}

实例九:

80 ======> 443 访问80端口跳转到443端口
server {
    
    
listen 80;
server_name www.xingyun.com xingyun.com;
return 301 https://www.xingyun.com$request_uri;
}
server {
    
    
listen 443 ssl;
server_name www.xingyun.com;
ssl on;
ssl_certificate /usr/local/nginx/conf/cert.pem;
ssl_certificate_key /usr/local/nginx/conf/cert.key;:
}

到这里就结束了,大家多多练习,多多联想。。。

猜你喜欢

转载自blog.csdn.net/weixin_45961525/article/details/108239454