Nginx:Rewrite

1. Commonly used Nginx regular expressions

^ :匹配输入字符串的起始位置
$ :匹配输入字符串的结束位置
* :匹配前面的字符零次或多次。如“ol*”能匹配“o”及“ol”、“oll”
+ :匹配前面的字符一次或多次。如“ol+”能匹配“ol”及“oll”、“olll”,但不能匹配“o”
? :匹配前面的字符零次或一次,例如“do(es)?”能匹配“do”或者“does”,”?”等效于”{0,1}”
. :匹配除“\n”之外的任何单个字符,若要匹配包括“\n”在内的任意字符,请使用诸如“[.\n]”之类的模式
\ :将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如“\n”匹配一个换行符,而“\$”则匹配“$”
\d :匹配纯数字[0-9]   \s :空白符    \w :任意单词字符包括下划线[A-Za-z0-9_]
{n} :重复 n 次
{n,} :重复 n 次或更多次
{n,m} :重复 n 到 m 次
[] :定义匹配的字符范围
[c] :匹配单个字符 c
[a-z] :匹配 a-z 小写字母的任意一个
[a-zA-Z0-9] :匹配所有大小写字母或数字
() :表达式的开始和结束位置
| :或运算符
  • From the function point of view, rewrite and location seem to be a bit similar, both of which can realize jump, the main difference is that rewrite 是在同一域名内更改获取资源的路径, and location 是对一类路径做控制访问或反向代理,还可以proxy_pass 到其他机器.
    rewrite 对访问的域名或者域名内的URL路径地址重写
    location 对访问的路径做访问控制或者代理转发

two, location

2.1 location can be roughly divided into three categories

1. Exact match: location = / {…}
2. General match: location / {…}
3. Regular match: location ~ / {…}

2.2 common location matching rules

= :进行普通字符精确匹配,也就是完全匹配。
^~ :表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其它 正则匹配location。
~ :区分大小写的匹配。
~* :不区分大小写的匹配。
!~ :区分大小写的匹配取非。
!~* :不区分大小写的匹配取非。

2.3 location priority

  • 精准匹配= > 前缀匹配^~(可以理解为特殊的前缀匹配) > 正则匹配\~ > 一般前缀匹配(不带任何修饰符的) > 通用匹配/
  • 1. Benchmark matching: Needless to say, this is just right, and there are no multiples or disputes.
  • 2. Prefix matching ^~ (can be understood as a special prefix matching): When there is no exact match but there are two special prefix matches, then when a match is found, whoever matches the longest will take priority. (For example: www.abcde.com location ^ab and location ^abc then the latter one has higher priority.
  • 3. Regex match~: When there is no exact match or special prefix match, the priority of multiple regular matches depends on the top and bottom, and whoever is on top has a higher priority.
  • 4. General prefix matching (without any modifiers): When there are no previous three types, the priority of multiple general prefix matching depends on the length of the matching characters, which is the same as the second one.
  • 5. Universal Matching: The priority is the lowest, and the universal matching will only be used when there is no other or no matching.
  • location example description:
(1)location = / {}
=为精确匹配 / ,主机名后面不能带任何字符串,比如访问 / 和 /data,则 / 匹配,/data 不匹配
再比如 location = /abc,则只匹配/abc ,/abc/或 /abcd不匹配。若 location  /abc,则即匹配/abc 、/abcd/ 同时也匹配 /abc/。

(2)location / {}
因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求 比如访问 / 和 /data, 则 / 匹配, /data 也匹配,
但后面前缀路径会和最长字符串优先匹配(最长匹配)

(3)location /documents/ {}
匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索其它 location
只有其它 location后面的前缀路径没有匹配到时,才会采用这一条

(4)location /documents/abc {}
匹配任何以 /documents/abc 开头的地址,匹配符合以后,还要继续往下搜索其它 location
只有其它 location后面的前缀路径没有匹配到时,才会采用这一条

(5)location ^~ /images/ {}
匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条

(6)location ~* \.(gif|jpg|jpeg)$ {}
匹配所有以 gif、jpg或jpeg 结尾的请求
然而,所有请求 /images/ 下的图片会被 location ^~ /images/ 处理,因为 ^~ 的优先级更高,所以到达不了这一条正则

(7)location /images/abc {}
最长字符匹配到 /images/abc,优先级最低,继续往下搜索其它 location,会发现 ^~ 和 ~ 存在

(8)location ~ /images/abc {}
匹配以/images/abc 开头的,优先级次之,只有去掉 location ^~ /images/ 才会采用这一条

(9)location /images/abc/1.html {}
匹配/images/abc/1.html 文件,如果和正则location ~ /images/abc/1.html 相比,正则优先级更高

2.4 In actual website usage, there are at least three matching rule definitions

#第一个必选规则
直接匹配网站根目录首页,通过域名访问网站首页比较频繁,使用这个会加速处理,比如说官网。
可以是一个静态首页,也可以直接转发给后端应用服务器
location = /index.html {
    root   html;
	index  index.html index.htm;
}

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

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

#第三个规则就是通用规则,比如用来转发带.php、.jsp后缀的动态请求到后端应用服务器
非静态文件请求就默认是动态请求
location / {
    proxy_pass http://tomcat_server;
}

Three, rewrite

3.1 rewrite function

  • Use the global variables provided by nginx or the variables set by yourself, combined with regular expressions and flag bits to achieve URL rewriting and redirection. For example: after changing the domain name, it is necessary to keep the old domain name able to jump to the new domain name, a certain web page needs to jump to the new page, anti-leeching of the website, etc.
  • rewrite 只能放在server{},location{},if{}中 , and , for example 默认只能对域名后边的除去传递的参数外的字符串起作用,
    http://www.kgc.com/abc/bbs/index.php?a=1&b=2 only rewrites /abc/bbs/index.php.

3.2 rewrite jump implementation

1. Nginx: The ngx_http_rewrite_module module supports URL rewriting and if condition judgment, but does not support else 2.
Jump: Jump from one location to another, and the cycle can be executed up to 10 times. After exceeding, nginx will return 500 errors
3. PCRE support: perl-compatible regular expression grammar rule matching
4. Rewrite module set command: create a new variable and set its value

3.3 rewrite execution sequence

1. Execute the rewrite command in the server block.
2. Perform location matching.
3. Execute the rewrite command in the selected location.

3.4 Syntax format

rewrite <regex> <replacement> [flag];
regex :表示正则匹配规则。
replacement :表示跳转后的内容。
flag :表示 rewrite 支持的 flag 标记。

#flag标记说明
last :本条规则匹配完成后,不终止重写后的url匹配,一般用在 server 和 if 中。
break :本条规则匹配完成即终止,终止重写后的url匹配,一般使用在 location 中。
redirect :返回302临时重定向,浏览器地址会显示跳转后的URL地址。
permanent :返回301永久重定向,浏览器地址栏会显示跳转后的URL地址。

4. Example of rewrite

4.1 Jump based on domain name

#现在公司旧域名www.kgc.com有业务需求变更,需要使用新域名www.benet.com代替,但是旧域名不能废除,需要跳转到新域名上,而且后面的参数保持不变。
vim /usr/local/nginx/conf/nginx.conf
server {
	listen       80;
	server_name  www.kgc.com;		#域名修改	
	charset utf-8;
	access_log  /var/log/nginx/www.kgc.com-access.log;		#日志修改
	location / {
	#添加域名重定向
        if ($host = 'www.kgc.com'){						#$host为rewrite全局变量,代表请求主机头字段或主机名
			rewrite ^/(.*)$ http://www.benet.com/$1 permanent;	#$1为正则匹配的内容,即“域名/”之后的字符串
        }
        root   html;
        index  index.html index.htm;
    }
}


echo "192.168.119.10 www.kgc.com www.benet.com" >> /etc/hosts
systemctl restart nginx
浏览器输入模拟访问 http://www.kgc.com/test/1.html(虽然这个请求内容是不存在的)
会跳转到www.benet.com/test/1.html,查看元素可以看到返回301,实现了永久重定向跳转,而且域名后的参数也正常跳转。

insert image description here

4.2 Access jump based on client IP

#今天公司业务新版本上线,要求所有 IP 访问任何内容都显示一个固定维护页面,只有公司 IP :192.168.119.10访问正常。
vim /usr/local/nginx/conf/nginx.conf
server {
	listen       80;
	server_name  www.kgc.com;		#域名修改	
	charset utf-8;
	access_log  /var/log/nginx/www.kgc.com-access.log;		#日志修改

	#设置是否合法的IP标记
    set $rewrite true;							#设置变量$rewrite,变量值为boole值true
    #判断是否为合法IP
	if ($remote_addr = "192.168.119.10"){		#当客户端IP为192.168.119.10时,将变量值设为false,不进行重写
        set $rewrite false;
    }
	#除了合法IP,其它都是非法IP,进行重写跳转维护页面
    if ($rewrite = true){						#当变量值为true时,进行重写
        rewrite (.+) /weihu.html;				#将域名后边的路径重写成/weihu.html后转发,例如www.kgc.com/weihu.html
    }
    location = /weihu.html {
        root /var/www/html;						#网页返回/var/www/html/weihu.html的内容
    }
	
	location / {
        root   html;
        index  index.html index.htm;
    }
}


mkdir -p /var/www/html/
echo "<h1>We are maintaining now!</h1>" > /var/www/html/weihu.html
systemctl restart nginx
只有 IP 为 192.168.119.10 能正常访问,其它地址都是维护页面

如果rewrite (.+) /weihu.html; 换成rewrite (.+) /weihu.html permanent; 的话,若不是 192.168.119.10 的主机访问会使浏览器修改请求访问的 URL 成 http://www.kgc.com/weihu.html 再请求访问,这样就会进入一直在 rewrite 的死循环,访问请求会一直被重写成 http://www.kgc.com/weihu.html 再请求访问
insert image description here

insert image description here

4.3 Jump to the new domain name based on the old domain name and add a directory

#现在访问的是 http://bbs.kgc.com/post/,现在需要将这个域名下面的访问都跳转到http://www.kgc.com/bbs/post/
vim /usr/local/nginx/conf/nginx.conf
server {
	listen       80;
	server_name  bbs.kgc.com www.kgc.com;		#域名修改	
	charset utf-8;
	access_log  /var/log/nginx/www.kgc.com-access.log;
	#添加
	location /post {
        rewrite (.+) http://www.kgc.com/bbs$1 permanent;		#这里的$1为位置变量,代表/post
    }
	
	location / {
        root   html;
        index  index.html index.htm;
    }
}


mkdir -p /usr/local/nginx/html/bbs/post
echo "this is 1.html"  >> /usr/local/nginx/html/bbs/post/1.html
echo "192.168.119.10 bbs.kgc.com"  >> /etc/hosts
systemctl restart nginx
使用浏览器访问 http://bbs.kgc.com/post/1.html 跳转到 http://www.kgc.com/bbs/post/1.html

insert image description here

4.4 Jump based on parameter matching

#现在访问http://www.kgc.com/100-(100|200)-100.html 跳转到http://www.kgc.com页面。
vim /usr/local/nginx/conf/nginx.conf
server {
	listen       80;
	server_name  www.kgc.com;		#域名修改	
	charset utf-8;
	access_log  /var/log/nginx/www.kgc.com-access.log;
	
	if ($request_uri ~ ^/100-(100|200)-(\d+).html$) {
        rewrite (.+) http://www.kgc.com permanent;
    }

	location / {
        root   html;
        index  index.html index.htm;
    }
}

systemctl restart nginx
使用浏览器访问 http://www.kgc.com/100-200-100.html 或 http://www.kgc.com/100-100-100.html 跳转到http://www.kgc.com页面。

insert image description here

$request_uri:包含请求参数的原始URI,不包含主机名,如:http://www.kgc.com/abc/bbs/index.html?a=1&b=2 中的 /abc/bbs/index.php?a=1&b=2 $uri:这个变量指当前的请求URI,不包括任何参数,如:/abc/bbs/index.html $document_uri:与$uri相同,这个变量指当前的请求URI,不包括任何传递参数,如:/abc/bbs/index.html

4.5 Jump based on all files ending in php in the directory

#要求访问 http://www.kgc.com/upload/123.php 跳转到首页。
vim /usr/local/nginx/conf/nginx.conf
server {
	listen       80;
	server_name  www.kgc.com;		#域名修改	
	charset utf-8;
	access_log  /var/log/nginx/www.kgc.com-access.log;
	
	location ~* /upload/.*\.php$ {
        rewrite (.+) http://www.kgc.com permanent;
    }

	location / {
        root   html;
        index  index.html index.htm;
    }
}


systemctl restart nginx
浏览器访问 http://www.kgc.com/upload/123.php 跳转到http://www.kgc.com页面。

insert image description here
insert image description here

4.6 Jump based on the most common url request

#要求访问一个具体的页面如 http://www.kgc.com/abc/123.html 跳转到首页
vim /usr/local/nginx/conf/nginx.conf
server {
	listen       80;
	server_name  www.kgc.com;		#域名修改	
	charset utf-8;
	access_log  /var/log/nginx/www.kgc.com-access.log;
	
    location ~* ^/abc/123.html {
        rewrite (.+) http://www.kgc.com permanent;
    }

	location / {
        root   html;
        index  index.html index.htm;
    }
}


systemctl restart nginx
浏览器访问 http://www.kgc.com/abc/123.html 跳转到http://www.kgc.com页面。

insert image description here

insert image description here

Guess you like

Origin blog.csdn.net/2301_76875445/article/details/131033040