概述
目录
一、Nginx Rewrite概述
1.1 什么是Nginx Rewrite
1.2 Rewrite跳转场景
1.3 Rewrite 跳转实现
1.4 Rewrite 实际场景
1.4.1 Nginx 跳转需求的实现方式
1.4.2 rewrite 放在 server{},if{},location{} 段中
1.4.3 对域名或参数字符串
二、Nginx 正则表达式
2.1 常用的正则表达式元字符
2.2 Nginx 和Apache 的区别
三、Rewrite 命令详解
3.1 Rewrite 命令语法
3.2 flag 标记
3.3 last 和 break 比较
四、location 分类和优先级
4.1 location 分类
4.2 正则匹配的常用表达式
4.3 location 优先级
4.3.1 location优先级规则
4.3.2 优先级示例
4.3.3 可用作判断的全局变量
4.4 rewrite 和 location 比较
4.5 实际网站使用中,至少有三个匹配规则定义
五、常用的Rewrite案例
5.1 基于域名的跳转
5.2 基于客户端IP访问跳转
5.3 基于旧域名跳转到新域名后面加目录
5.4 基于参数匹配的跳转
5.5 基于目录下所有php结尾的文件跳转
5.6 基于最普通一条 url 请求的跳转
六、总结
一、Nginx Rewrite概述
1.1 什么是Nginx Rewrite
现在Nginx已经成为很多公司作为前端反向代理服务器的首选,在实际工作中往往会遇到很多跳转(重写URL)的需求。比如更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求。如果在后端使用的Apache服务器,虽然也能做跳转,规则库也很强大,但是用Nginx跳转效率会更高。
1.2 Rewrite跳转场景
调整用户浏览的 URL,看起来更规范,合乎开发及产品人员的需求。
为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态URL地址伪装成静态地址提供服务。
网址换新域名后,让旧的访问跳转到新的域名上。例如,访问京东的 360buy.com 会跳转到 jd.com。
服务端某些业务调整,比如根据特殊变量、目录、客户端的信息进行 URL 调整等。
ps:URL:就是具体的路径、位置。
URL:指的是一个拥有相同类型,特性的对象集合
1.3 Rewrite 跳转实现
1.Nginx 是通过 ngx_http_rewrite_module 模块支持 url 重写、支持 if 条件判断,但不支持 else
2.该模块需要PCRE 支持,应在编译 Nginx 时指定 PCRE 支持,默认已经安装。根据相关变量重定向和选择不同的配置,从一个location跳转到另一个location,不过这样的循环最多可以执行10次,超过后 Nginx 将返回500错误。
3.同时,重写模块包含 set 指令,来创建新的变量并设其值,这在有些情景下非常有用的,如记录条件标识、传递参数到其他 location、记录做了什么等等。
4.rewrite 功能就是,使用 Nginx 提供的全局变量或自己设置的变量,结合正则表达式和标志位实现 URL 的重写以及重定向。
1.4 Rewrite 实际场景
1.4.1 Nginx 跳转需求的实现方式
使用 rewrite 进行匹配跳转
使用 if 匹配全局变量后跳转
使用 location 匹配再跳转
rewrite执行顺序
(1) 执行server块里面的rewrite指令
(2) 执行location匹配
(3) 执行选定的location中的rewrite指
1.4.2 rewrite 放在 server{},if{},location{} 段中
location 只对域名后边的除去传递参数外的字符串起作用——页面文件的路径
1.4.3 对域名或参数字符串
使用 if 全局变量匹配
使用 proxy_pass 反向代理
二、Nginx 正则表达式
2.1 常用的正则表达式元字符
字符 | 说明 |
^ | 匹配输入字符串的起始位置 |
$ | 匹配输入字符串的结束位置 |
* | 匹配前面的字符零次或多次 |
+ | 匹配前面的字符一次或多次 |
? | 匹配前面的字符零次或一次 |
. | 匹配除”n”之外的任何单个字符 |
将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用 | |
d | 匹配纯数字 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
[c] | 匹配单个字符c |
[a-z] | 匹配a-z小写字母的任意一个 |
[a-zA-Z] | 匹配a-z小写字母或A-Z大写字母的任意一个 |
正则表达式:---》为了精确匹配,用户体验,筛选 正则匹配的意义所在
localtion 需要精确匹配到 index.html
注意:从功能上看rewrite 和 location 似乎有点像,都能实现跳转,主要区别在于rewrite是在同一域名更改获取资源的路径,而location 是对一类路径做控制访问或反向代理,还可以proxy_pass到其他机器。
2.2 Nginx 和Apache 的区别
正则表达式是二者的区别之一
正则表达式:可以更加精确的匹配需求的字符串/参数/位置等
三、Rewrite 命令详解
3.1 Rewrite 命令语法
rewrite <regex> <replacement> [flag];
#<regex>:正则表达式
#<replacement>:跳转后的内容
#[flag]rewrite支持的flag标记
示例:rewrite是实现URL重写的关键指令,根据regex(正则表达式)部分的内容,重定向到replacement部分,结尾是flag标记。
下面是一个简单地URL rewrite跳转的例子:
在上述指令中,rewrite为固定关键字,表示开启一条rewrite匹配规则;
regex部分是^/(.*)是一个正则表达式,表示匹配所有,匹配成功后跳转到http://www.etiantian.org/$1;
这里的$1是取前面regex部分括号里的内容;
结尾的permanent是永久301重定向标记,即跳转到后面的http://www.etiantian.org/$1地址上。
3.2 flag 标记
标记 | 说明 |
last | 相当于Apache的[L]标记,表示完成rewrite |
break | 本条规则匹配完成即终止,不再匹配后面的任何规则 |
redirect | 返回302临时重定向,浏览器地址会显示跳转后的URL地址,爬虫不会更新url |
permanent | 返回301永久重定向,浏览器地址会显示跳转后的URL地址,爬虫更新url |
3.3 last 和 break 比较
last | break | |
使用场景 | 一般写在 server 和 if 中 | 一般使用在 location 中 |
URL匹配 | 不终止重写后的 urI 匹配 | 终止重写后的 url 匹配 |
last:url 重写后,马上发起一个新请求,再次进入 server 块,重试 location 匹配,超过10次匹配不到报 500 错误,地址栏不变;
break:url重写后,直接使用当前资源,不再使用 location 余下的语句,完成本次请求,地址栏不变
总的来说:last 和 break 再重定向后,地址栏都不会发生变化,这是他们的相同点。不同点在于 last 会写在 server 和 if中,break 是写在location 中,last 不会终止重写后的 url 匹配,break 会终止重写后的 url 匹配。
四、location 分类和优先级
4.1 location 分类
location = patt {} [精准匹配] #精确匹配字符串
location patt {} [一般匹配] #只要包含patt的字符串即可
location ~ patt {} [正则匹配] #按照正则表达式的方式匹配
4.2 正则匹配的常用表达式
标记 | 说明 |
~ | 执行一个正则匹配,区分大小写 |
~* | 执行一个正则匹配,不区分大小写 |
!~ | 执行一个正则匹配,区分大小写不匹配 |
!~* | 执行一个正则匹配,不区分大小写不匹配 |
^~ | 普通字符匹配,使用前缀匹配,如果匹配成功,则不再匹配其他location |
= | 普通字符精确匹配,也就是完全匹配 |
@ | 定义一个命名的location,使用在内部定向时 |
4.3 location 优先级
相同类型的表达式,字符串长的会优先匹配
按优先级匹配
= 类型 #首先精确匹配
^~ 类型表达式 #其次前缀匹配
正则表达式(~和~*)类型 #其次是按文件中顺序的正则匹配
常规字符串匹配类型,按前缀匹配 #然后匹配不带任何修饰的前缀匹配
通用匹配(/),如果没有其他匹配,任何请求都会匹配到 #最后交给 / 通用匹配
4.3.1 location优先级规则
匹配某个具体文件
(location=完整路径) > (location ^~ 完整路径) > (location ~ 完整路径) >(location~*完整路径) > (location部分起始路径) > (location /)
用目录做匹配访问某个文件
(location=目录) > (location ^ ~ 目录/) > (location ~ 目录 ) > (location~*目录) > (location目录) > (location /)
总结:location 匹配
首先看 优先级:精确 > 前缀 > 正则 > 一般 > 通用
优先级相同:正则看上下顺序,上面的优先;一般匹配看长度,最长匹配的优先
精确、前缀、正则、一般 都没有匹配到,最后再看通用匹配
4.3.2 优先级示例
-------------------------------------------------------------------------------------------------
location = / {
[configuration A]
}
#精确匹配,主机名后面不能带任何字符串,比如访问/和/data,则/匹配,/data不匹配;
比如location = /abc,则只匹配/abc,/abc/或/abcd不匹配;
若location /abc,则匹配/abc、/abcd/ 同时也匹配/abc/
-------------------------------------------------------------------------------------------------
location / {
[configuration B]
}
#一般匹配,所有的地址都以/开头,这条规则将匹配到所有请求,比如访问/和data,则/匹配,/data也匹配,但若后面是正则表达式和最长字符会优先匹配
------------------------------------------------------------------------------------------------
location /documents/ {
[configuration C]
}
#匹配任何以/documents/开头的地址,匹配符合以后,还要继续往下搜索其他location,只有当后面的正则表达式没有匹配到时,才会采用这一条
------------------------------------------------------------------------------------------------
location ~ /documents/abc {
[configuration D]
}
#匹配任何以/documents/abc开头的地址,匹配符合以后,还要继续往下搜索其他location,只有当后面的正则表达式没有匹配到时,才会采用这一条
------------------------------------------------------------------------------------------------
location ^~ /images/ {
[configuration E]
}
#匹配任何以/images/开头的地址,匹配符合以后,停止往下匹配
------------------------------------------------------------------------------------------------
location ~* .(gif|jpg|jpeg)$ {
[configuration F]
}
#匹配所有以gif,jpg或jpeg结尾的请求,因为 ^~ 的优先级最高
------------------------------------------------------------------------------------------------
location ~ /images/abc {
[configuration G]
}
#匹配以/images/abc开头的,优先级次之,只有去掉location ^~ /images/才会采用这一条
------------------------------------------------------------------------------------------------
location /images/abc/1.html {
[configuration H]
}
#匹配/images/abc/1.html文件,如果和正则location ~ /images/abc/1.html相比,正则优先级最高
----------------------------------------------------------------------------------------------
location /images/abc {
[configuration I]
}
#最长字符匹配到/images/abc,优先级最低,继续往下搜索其他location,会发现 ^~ 和 ~ 存在
-----------------------------------------------------------------------------------
4.3.3 可用作判断的全局变量
$args #这个变量等于请求行中的参数。
$content_length # 请求头中的Content-length字段。
$content_type # 请求头中的Content-Type字段。
$document_root # 当前请求在root指令中指定的值。
$host # 请求主机头字段,否则为服务器名称。
$http_user_agent # 客户端agent信息
$http_cookie # 客户端cookie信息
$limit_rate # 这个变量可以限制连接速率。
$request_body_file # 客户端请求主体信息的临时文件名。
$request_method # 客户端请求的动作,通常为GET或POST。
$remote_addr # 客户端的IP地址。
$remote_port # 客户端的端口。
$remote_user # 已经经过Auth Basic Module验证的用户名。
$request_filename # 当前请求的文件路径,由root或alias指令与URI请求生成。
$query_string # 与$args相同。
$scheme #HTTP 方法(如http,https)。
$server_protocol # 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$server_addr # 服务器地址,在完成一次系统调用后可以确定这个值。
$server_name # 服务器名称。
$server_port # 请求到达服务器的端口号。
$request_uri # 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
$uri # 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
$document_uri # 与$uri相同。
例:http://localhost:88/test1/test2/test.php
$host:localhost
$server_port:88
$request_uri:http://localhost:88/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:D:nginx/html
$request_filename:D:nginx/html/test1/test2/test.php
4.4 rewrite 和 location 比较
相同点:
都能实现跳转
不同点:
rewrite 是在同一域名内更改获取资源的路径
location是对一类路径控制访问或反向代理,还可以 proxy_pass 到其他机器
rewrite会写在location里,执行顺序
执行server块里面的rewrite指令
执行location匹配
执行选定的location中的rewrite指令
4.5 实际网站使用中,至少有三个匹配规则定义
第一个规则
直接匹配网站根,通过域名访问网站首页比较频繁,使用这个会加速处理,比如说官网。
可以是一个静态首页,也可以直接转发给后端应用服务器
location = / {
root html;
index index.html index.htm;
}
第二个规则
是处理静态文件请求,这是nginx作为http服务器的强项有两种配置模式,目录匹配或后缀匹配,任选其一或搭配使用
location ^~ /static/ {
root /webroot/static/ ;
}
location ~* .(gif|jpg|jpeg)$ {
root /webroot/static/ ;
}
第三个规则
就是通用规则,比如用来转发带.php、.jsp后缀的动态请求到后端应用服务器,非静态文件请求就默认是动态请求
location / {
proxy_pass http://tomcat_server;
}
五、常用的Rewrite案例
5.1 基于域名的跳转
现在公司旧域名www.changjiang.com有业务需求变更,需要使用新域名www.huanghe.com代替,但是旧域名不能废除,需要跳转到新域名上,而且后面的参数保持不变
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name www.changjiang.com; #域名修改
charset utf-8;
access_log/var/log/nginx/www.changjiang.com-access.log; #日志修改
location / {
#添加域名重定向
if ($host = 'www.changjiang.com' ) { #$host为rewrite全局变量,代表请求主机头字段或主机名
rewrite ^/(.*)$http://www .huanghe.com/$1 permanent; #$1为正则匹配的内容,即"域名/“之后的字符串
}
root html;
index index.html index.htm;
}
}
echo "192.168.111.40 www.changjiang.com www.huanghe.com" >>/etc/hosts
systemctl restart nginx
浏览器输入模拟访问http://www.changjiang.com/changjiang/1.html(虽然这个请求内容是不存在的)
会跳转到www.huanghe.com/changjiang/1.html,查看元素可以看到返回301,实现了永久重定向跳转,而且域名后的参数也
正常跳转
5.2 基于客户端IP访问跳转
今天公司业务新版本上线,要求所有I访问任何内容都显示一个固定维护页面,只有公司IP : 192.168.111.40访问正常。
vim /usr/ local/nginx/conf/nginx.conf
server {
listen 80;
server name www.changjiang.com; #域名修改
charset utf-8;
access_log /var/log/nginx/www.changjiang.com-access.log; #日志修改
#设置是否合法的IP标记
set $rewrite true; #设置变量$rewrite,变量值为boole值true
#判断是否为合法IP
if ($remote_addr = "192.168.111.40") { #当客户端IP为192.168.111.40时,将变量值设为false,不进行重写
set $rewrite false;
}
#除了合法IP,其它都是非法IP,进行重写跳转维护页面
if ($rewrite = true) { #当变量值为true时,进行重写
rewrite (.+) /weihu.html; #将域名后边的路径重写成/weihu.html,
例如www.changjiang.com/weihu.html
}
location = /weihu.html {
root /var/www/html;
#网页返回/var/www/html/weihu.html的内容
}
location / {
roothtml;
index index.html index.htm;
}
}
systemctl restart nginx
只有 IP 为 192.168.111.40 能正常访问,其它地址都是维护页面
如果rewrite (.+)/weihu.html;改成rewrite (.+)/weihu.html permanent;的话,如果是非92.168.111.40的主机访问会使浏览器修改请求访问的URL成 http:.//www.changjiang.com/weihu.html再请求访问,这样就会进入一直在rewrite的死循环,访问请求会一直被重写成http://www.changjiang.com/weihu.html再请求访问
在/var目录下创建一个站点文件
使用另一主机访问时:会转到weihu.html的界面
5.3 基于旧域名跳转到新域名后面加目录
现在访问的是 http://bbs.changjiang.com/post/,现在需要将这个域名下面的访问都跳转到http://www.changjiang.com/bbs/post/
vim /usr/ local/nginx / conf/nginx.conf
server {
listen 80;
server_name bbs.changjiang.com; #域名修改
charset utf-8;
access_log/var/log/nginx/www.changjiang.com-access.log;
#添加
location /post {
rewrite (.+) http: //www.changjiang.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.htmlecho
"192.168.111.40 bbs.changjiang.com">>letc/ hosts
systemctl restart nginx
使用浏览器访问http://bbs.changjiang.com/post/1.html跳转到http://www.changjiang.com/bbs/post/1.html
5.4 基于参数匹配的跳转
现在访问http://www.changjiang.com/100-(100|200)-100.html跳转到http://www.changjiang.com页面。
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server name www. chagngjiang.com; #域名修改
charset utf-8;
access_log/var/log/nginx/www.changjiang.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.service 重启服务
注意:100-(100|200)这是固定的不能改变,不然会报错
5.5 基于目录下所有php结尾的文件跳转
要求访问http: // www.changjiang.com/upload/520.php 跳转到首页。
vim /usr/local/nginx/ conf/nginx.conf
server {
listen 80;
server name www.changjiang.com; #域名修改
charset utf-8;
access_log/var/ log/nginx/www.changjiang.com-access.log;
location ~*/upload/.*.php$ {
rewrite (.+) http: // www .changjiang.com permanent;
}
location / {
root html;
index index.html index.htm;
}
}
systemctl restart nginx
浏览器访问http: //www.changjiang.com/upload/123.php
跳转到http:// www.changjiang.com页面。
或者可以使用任意字符:
5.6 基于最普通一条 url 请求的跳转
要求访问一个具体的页面如 http://www.changjiang.com/abc/123.html 跳转到首页
vim /usr/local/nginx/conf/nginx.conf
server {
listen 80;
server_name www.changjiang.com; #域名修改
charset utf-8;
access_log /var/log/nginx/www.changjiang.com-access.log;
location ~* ^/kgc/wd123.html {
rewrite (.+) http://www.changjiang.com permanent;
}
location / {
root html;
index index.html index.htm;
}
}
systemctl restart nginx
浏览器访问 http://www.changjiang.com/kgc/wd123.html 跳转到http://www.changjiang.com页面。
方法一: 使用location 模块判断
注意:浏览器访问的域名http://www.changjiang.com/kgc/wd123.html 红色的部分是固定的,不能改变
方法二:使用if 模块
六、总结
1. Rewrite 跳转场景
2. Rewrite 的执行顺序
(1) 执行server块里面的rewrite指令
(2) 执行location匹配
(3) 执行选定的location中的rewrite指
3. location 的分类
精确匹配
一般匹配
正则匹配
4. location 的优先级
(location = 完整路径) > (location ^~ 路径) > (location ~,~* 正则顺序) > (location 部分起始路径) > (location /)
5. Rewrite 使用方法
(1)基于域名的跳转
(2)基于客户端 IP 访问跳转
(3)基于旧域名跳转到新域名后面加目录
(4)基于参数匹配的跳转
(5)基于目录下所有 php 结尾的文件跳转
(6)基于最普通一条 url 请求的跳转
最后
以上就是淡然长颈鹿为你收集整理的Nginx Rewrite概述分类和优先级一、Nginx Rewrite概述二、Nginx 正则表达式三、Rewrite 命令详解四、location 分类和优先级五、常用的Rewrite案例六、总结 的全部内容,希望文章能够帮你解决Nginx Rewrite概述分类和优先级一、Nginx Rewrite概述二、Nginx 正则表达式三、Rewrite 命令详解四、location 分类和优先级五、常用的Rewrite案例六、总结 所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复