目录
一、location
1.location 匹配规则介绍
2. 实际网站使用中匹配规则
2.1第一个必选规则
2.2第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
2.3第三个规则就是通用规则
3.location 匹配规则演示
2.1一般前缀匹配
2.2正则匹配
2.3正则前缀匹配
2.4精准匹配
二、rewrite
1.rewrite介绍
1.1rewrite功能
1.2rewrite重写跳转
2.rewrite命令的执行
2.1rewrite执行顺序
2.2rewrite语法格式
3.rewrite 示例
3.1基于域名的跳转
3.2基于客户端IP访问跳转
3.3 基于旧域名跳转到新域名后面加目录
3.4 基于参数匹配的跳转
一、location
1.location 匹配规则介绍
location 匹配规则分类:
- 精准匹配:location = / { ……}
- 一般匹配:location / {……}
- 正则匹配:location ~ / {……}
location 常用匹配规则:
- =:进行普通字符精准匹配,也就是完全匹配即匹配路径与访问路径完全一致。
- ^~:表示普通字符匹配。使用前缀匹配,如果匹配成功,则不再匹配其它正则匹配 location
- ~:区分大小写的匹配。
- ~*:不区分大小写的匹配。
- !~:区分大小写的匹配取非。
- !~*:不区分大小写的匹配取非。
location 优先级:
- 首先精准匹配 =
- 其次前缀匹配 ^~
- 其次是按文件中顺序的正则 ~ 或~*,正则匹配到以后,不再向下匹配
- 然后匹配不带任何修饰符的一般前缀匹配
- 最后是交给 / 通用匹配
总结:
- 精准匹配= > 正则前缀匹配^~ > 正则匹配 > 一般前缀匹配 > 通用匹配
- 正则匹配:一旦匹配到,则不再向下匹配
location 示例说明:
- location = / {}:=为精确匹配 / ,主机名后面不能带任何字符串,比如访问 / 和 /data,则 / 匹配,/data 不匹配;再比如 location = /abc,则只匹配/abc ,/abc/或 /abcd不匹配。
- location / {}:因为所有的地址都以 / 开头,所以这条规则将匹配到所有请求 比如访问 / 和 /data, 则 / 匹配, /data 也匹配,但后面前缀路径会和最长字符串优先匹配(最长匹配)
- location /documents/ {}:匹配任何以 /documents/ 开头的地址,匹配符合以后,还要继续往下搜索其它 location;只有其它 location后面的前缀路径没有匹配到时,才会采用这一条
- location /documents/abc {}:匹配任何以 /documents/abc 开头的地址,匹配符合以后,还要继续往下搜索其它 location;只有其它 location后面的前缀路径没有匹配到时,才会采用这一条
- location ^~ /images/ {}:匹配任何以 /images/ 开头的地址,匹配符合以后,停止往下搜索正则,采用这一条
- location ~* \.(gif|jpg|jpeg)$ {}:匹配所有以 gif、jpg或jpeg 结尾的请求。然而,所有请求 /images/ 下的图片会被 location ^~ /images/ 处理,因为 ^~ 的优先级更高,所以到达不了这一条正则
- location /images/abc {}:最长字符匹配到 /images/abc,优先级最低,继续往下搜索其它 location,会发现 ^~ 和 ~ 存在
- location ~ /images/abc {}:匹配以/images/abc 开头的,优先级次之,只有去掉 location ^~ /images/ 才会采用这一条
- location /images/abc/1.html {}:匹配/images/abc/1.html 文件,如果和正则location ~ /images/abc/1.html 相比,正则优先级更高
2. 实际网站使用中匹配规则
2.1第一个必选规则
直接匹配网站根目录首页,通过域名访问网站首页比较频繁,使用这个会加速处理,比如说官网。
可以是一个静态首页,也可以直接转发给后端应用服务器
location = /index.html {
root html;
index index.html index.htm;
}
2.2第二个必选规则是处理静态文件请求,这是nginx作为http服务器的强项
有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
root /webroot/;
}
location ~* \.(gif|jpg|jpeg|png|css|js|ico)$ {
root /webroot/res/;
}
2.3第三个规则就是通用规则
比如用来转发带.php、.jsp后缀的动态请求到后端应用服务器
非静态文件请求就默认是动态请求
location / {
proxy_pass http://tomcat_server;
}
3.location 匹配规则演示
2.1一般前缀匹配
#将原本配置文件备份
mv /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.conf.bak
#还原配置文件
mv /usr/local/nginx/conf/nginx.conf.default /usr/local/nginx/conf/nginx.conf
vim /usr/local/nginx/conf/nginx.conf
location / { #通用配置
root html;
index index.html index.htm;
}
location /abc { #一般前缀匹配
root /var/www;
}
location /abc/test { #一般前缀匹配
root /var/data;
}
systemctl restart nginx.service
#匹配到 /abc 则访问结果:this is test web
mkdir -p /var/www/abc/test
echo '<h1>this is test web</h1>' > 123.html
#匹配到 /abc/test 则访问结果:welcome to test web
mkdir -p /var/data/abc/test
echo '<h1>welcome to test web</h1>' > 123.html
浏览器访问验证:
http://192.168.88.40/abc/test/123.html
2.2正则匹配
vim /usr/local/nginx/conf/nginx.conf
location / { #通用配置
root html;
index index.html index.htm;
}
location ~ ^/abc { #正则匹配
root /var/www;
}
location ~ ^/abc/test { #正则匹配
root /var/data;
}
systemctl restart nginx.service
#匹配到 /abc 则访问结果:this is test web
mkdir -p /var/www/abc/test
echo '<h1>this is test web</h1>' > 123.html
#匹配到 /abc/test 则访问结果:welcome to test web
mkdir -p /var/data/abc/test
echo '<h1>welcome to test web</h1>' > 123.html
浏览器访问验证:
http://192.168.88.40/abc/test/123.html
2.3正则前缀匹配
vim /usr/local/nginx/conf/nginx.conf
location / { #通用配置
root html;
index index.html index.htm;
}
location ~ ^/abc { #正则匹配
root /var/www;
}
location ^~ /abc/test { #正则前缀匹配
root /var/data;
}
systemctl restart nginx.service
#匹配到 /abc 则访问结果:this is test web
mkdir -p /var/www/abc/test
echo '<h1>this is test web</h1>' > 123.html
#匹配到 /abc/test 则访问结果:welcome to test web
mkdir -p /var/data/abc/test
echo '<h1>welcome to test web</h1>' > 123.html
浏览器访问验证:
http://192.168.88.40/abc/test/123.html
2.4精准匹配
vim /usr/local/nginx/conf/nginx.conf
location / { #通用配置
root html;
index index.html index.htm;
}
location ~ ^/abc { #正则匹配
root /var/www;
}
location ^~ /abc/test { #正则前缀匹配
root /var/data;
}
location = /abc/test/123.html { #精准匹配
root html;
}
systemctl restart nginx.service
#匹配到 /abc 则访问结果:this is test web
mkdir -p /var/www/abc/test
echo '<h1>this is test web</h1>' > 123.html
#匹配到 /abc/test 则访问结果:welcome to test web
mkdir -p /var/data/abc/test
echo '<h1>welcome to test web</h1>' > 123.html
#匹配到 /abc/test/123.html 则访问结果:hello, test web
mkdir -p /usr/local/nginx/html/abc/test
echo '<h1>hello, test web</h1>' > 123.html
浏览器访问验证:
http://192.168.88.40/abc/test/123.html
二、rewrite
1.rewrite介绍
1.1rewrite功能
rewrite功能:使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标记位实现URL重写以及重定向。比如:更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等需求。
rewrite 与 location 的区别:
- rewrite:对访问的域名或域名内的URL路径地址重写
- location:对访问的路径做控制或代理转发
- 从功能看,rewrite 和 location 似乎有点像,都能实现跳转,主要区别在于 rewrite 是在同一域名内更改获取资源的路径,而 location 是对一类路径做控制访问或反向代理,还可以proxy_pass 到其他机器。
1.2rewrite重写跳转
rewrite位置: rewrite只能放在server{},location{},if{}中,并且默认只能对域名后边的除去传递的参数外的字符串起作用。
例如 http://www.kgc.com/abc/bbs/index.php?a=1&b=2 只对/abc/bbs/index.php重写。
rewrite跳转实现:
- Nginx:通过ngx_http_rewrite_module 模块支持URL重写、支持if条件判断,但不支持else
- 跳转:从一个 location跳转到另一个location,循环最多可以执行10次,超过后nginx将返回500错误
- PCRE支持:perl兼容正则表达式的语法规则匹配
- 重写模块 set 指令:创建新的变量并设其值
2.rewrite命令的执行
2.1rewrite执行顺序
rewrite 执行顺序如下:
- 执行 server 块里面的 rewrite 指令。
- 执行 location 匹配。
- 执行选定的 location 中的 rewrite 指令。
2.2rewrite语法格式
语法格式:rewrite <regex> <replacement> [flag];
regex :表示正则匹配规则。
replacement :表示跳转后的内容。
flag :表示 rewrite 支持的 flag 标记。
#flag标记说明
last :本条规则匹配完成后,不终止重写后的url匹配,一般用在 server 和 if 中。
break :本条规则匹配完成即终止,终止重写后的url匹配,一般使用在 location 中。
redirect :返回302临时重定向,浏览器地址会显示跳转后的URL地址。
permanent :返回301永久重定向,浏览器地址栏会显示跳转后的URL地址。
3.rewrite 示例
3.1基于域名的跳转
现在公司旧域名www.kgc.com有业务需求变更,需要使用新域名www.benet.com代替,但是旧域名不能废除,需要跳转到新域名上,而且后面的参数保持不变。
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name www.kgc.com;
# 添加域名重定向
if ($host = 'www.kgc.com' ) {
#$host为rewrite全局变量,代表请求主机头字段或主机名
rewrite ^/(.*)$ http://www.benet.com/$1 permanent;
# $1:为正则匹配的内容,即“域名/”之后的字符串
}
location / {
root html;
index index.html index.htm;
}
}
cd /usr/local/nginx/html
echo '<h1>this is test web</h1>' > test.html
echo "192.168.88.40 www.kgc.com www.benet.com" >> /etc/hosts
systemctl restart nginx
浏览器访问验证:
http:www.kgc.com/test.html 会跳转到 www.benet.com/test.html
3.2基于客户端IP访问跳转
今天公司业务新版本上线,要求所有 IP 访问任何内容都显示一个固定维护页面,只有公司 IP :192.168.88.40访问正常。
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name www.kgc.com;
#设置是否合法的IP标记
set $rewrite true; #设置变量$rewrite,变量值为boole值true
#判断是否为合法IP
if ( $remote_addr = "192.168.88.40") { #当客户端IP为192.168.88.40时,将变量值设为false,不进行重写
set $rewrite false;
}
#除了合法IP,其它都是非法IP,进行重写跳转维护页面
if ($rewrite = true) { #当变量值为true时,进行重写
rewrite ^/ /weihu.html; #将域名后边的路径重写成/weihu.html后转发,例如www.kgc.com/weihu.html
}
#网页返回/var/www/html/weihu.html的内容
location = /weihu.html {
root /var/www;
}
location / {
root html;
index index.html index.htm;
}
}
cd /usr/local/nginx/html
echo '<h1>the web is updating!</h1>' > weihu.html
systemctl restart nginx.service
浏览器访问验证:
只有 IP 为 192.168.88.40 能正常访问,其它地址都是维护页面
###注意事项
如果rewrite ^/ /weihu.html; 换成rewrite ^/ /weihu.html permanent; 的话,
若不是 192.168.80.10 的主机访问会使浏览器修改请求访问的 URL 成 http://www.kgc.com/weihu.html 再请求访问,
这样就会进入一直在 rewrite 的死循环,访问请求会一直被重写成 http://www.kgc.com/weihu.html 再请求访问
3.3 基于旧域名跳转到新域名后面加目录
现在访问的是 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;
location /bbs {
root /var/www;
}
location /post {
rewrite (.+) http://www.kgc.com/bbs$1 permanent;
}
location / {
root html;
index index.html index.htm;
}
}
mkdir -p /var/www/bbs/post
cd /var/www/bbs/post
echo '<h1>hello,world!</h1>' > 123.html
echo '192.168.88.40 bbs.kgc.com' >> /etc/hosts
systemctl restart nginx.service
使用浏览器访问 http://bbs.kgc.com/post/123.html 跳转到 http://www.kgc.com/bbs/post/123.html
3.4 基于参数匹配的跳转
现在访问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;
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.service
使用浏览器访问 http://www.kgc.com/100-200-100.html 或 http://www.kgc.com/100-100-100.html 跳转到http://www.kgc.com页面。
- $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