https://zhuanlan.zhihu.com/p/359801091

Rewrite主要的功能是实现URL重写,Nginx 的 Rewrite 规则采用 PCRE Perl 兼容正则表达式的语法进行规则匹配,如相使用 Nginx 的 Rewrite 功能,在编译 Nginx 前要编译安装 PCRE 库。Rewrite主要实现url地址重写,以及重定向,就是把传入web的请求重定向到其他url的过程。

一、rewrite介绍

rewrite和location的功能有点相像,都能实现跳转,主要区别在于rewrite常用于同一域名内更改获取资源的路径,而location是对一类路径做控制访问和反向代理,可以proxy_pass到其他服务器。

Nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。

rewrite只能放在server{},location{},if{}中,

并且只能对域名后边的除去传递的参数外的字符串起作用。

二、rewrite作用及应用场景

Rewrite主要的功能就是实现URL的重写,Nginx的Rewrite规则采用Pcre,perl兼容正则表达式的语法规则匹配,如果需要Nginx的Rewrite功能,在编译Nginx之前,需要编译安装PCRE库。通过Rewrite规则,可以实现规范的URL、根据变量来做URL转向及选择配置。

作用: 实现对URL的重写以及对匹配(正则表达式)的url的重定向

场景:

1. URL访问跳转, 支持开发设计

① 页面跳转 ② 兼容性支持 ③ 展示效果

2. SEO优化

3. 维护

① 后台维护 ② 流量转发

4. 安全

① 伪静态页面

配置语法

systax: rewrite [正则表达式 替换前的URL] [替换后的URL] [标识];

default: 无配置

二、ReWrite相关指令

指令 默认值 使用范围 作用

三、rewrite常用全局变量

四、Nginx rewrite语法

1、rewrite指令语法

指令语法: rewrite regex replacement [flag]

默认值: none

应用位置:server、location、if

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

下面是一个简单地URL rewrite跳转的例子:

rewrite ^/(.*) http://www.cjzzc.com/$1 permanent;

在上述指令中,rewrite为固定关键字,表示开启一条rewrite匹配规则,regex部分是^/(.*),这是一个正则表达式,表示匹配所有,匹配成功后跳转到http://www.cjzzc.com/$1。这里的$1是取前面regex部分括号里的内容结尾的permanent;是永久301重定向标记,即跳转到后面的http://www.cjzzc.com/$1地址上。

2、rewrite指令结尾的flag标记说明

flag标记符号 说 明

在以上的flag标记中,last和break用来实现URL重写,浏览器地址栏的URL地址不变,但在服务器访问的程序及路径发生了变化。redirect和permanent用来实现URL跳转,浏览器地址会显示跳转后的URL地址。

last和break标记的实现功能类似,但二者之间有细微的差别,使用alias指令时必须用last标记,使用proxy_pass指令时要使用break标记。

last标记在本条rewrite规则执行完毕后,会对其所在的server{…}标签重新发起请求,而break标记则会在本条规则匹配完成后,终止匹配,不再匹配后面的规则。

五、例子

1、 break

参数项:break,用于停止执行rewrite模块的指令,但是其他模块不受影响。

配置位置:server,location,if

示例

server {

listen 80;

server_name localhost;

#===== break && rewrite test =====

#这里如果注释掉break,所有请求进来都是返回http200,this is breaktest...

break;

return 200 "this is breaktest...";

location = /breaktest {

break;

return 200 $request_uri;

proxy_pass http://192.168.88.38/other;

}

location / {

return 200 $request_uri;

}

}

# 发送请求如下

# curl 127.0.0.1:8080/testbreak

# /other

# 可以看到 返回 `/other` 而不是 `/testbreak`,说明 `proxy_pass` 指令还是被执行了

# 也就是说 其他模块的指令是不会被 break 中断执行的

#(proxy_pass是ngx_http_proxy_module的指令)

测试链接:http://192.168.88.38/breaktest ,请求到达server块后,被break终止执行rewrite指令集,return属于rewrite模块指令集,所以return 200 “this is breaktest…”不会执行;

因为没有返回结果,所以继续执行location匹配,请求匹配到location = /breaktest{}之后,break终止return 200 $request_uri,而proxy_pass属于ngx_http_proxy_module,仍会继续执行,

反向代理后的新url匹配到location /{},因此最终返回结果为 http200,/other,如下图:

2、set

配置位置:server,location,if,用于为变量赋值

示例:

server {

listen 80;

server_name localhost;

#===== break && rewrite test =====

#这里如果注释掉break,所有请求进来都是返回http200,this is breaktest...

break;

return 200 "this is breaktest...";

location = /breaktest {

break;

return 200 $request_uri;

proxy_pass http://192.168.88.38/other;

}

location / {

#set赋值,可以直接赋字符串,或是变量,如下是变量和字符串的组合

set $set_value_test “112233 $request_uri”;

return 200 $set_value_test;

}

}

测试链接http://192.168.88.38/breaktest,使用效果如下图:

3.if

配置位置:server,location,用于依据指定的条件,决定是否执行if块中的语句

判断条件:

3.1.变量值为空或为0,都为false;

示例:

set $if_value_test “0”;

#注意这里if、()和{}要空格,否则会报错..略坑,不过这也是代码规范了

if ($if_value_test) {

#不会执行,因为$if_value_test值为0,false

return 200;

}

3.2.变量与字符串比较,=为等于,!=为不等

3.3.变量与正则表达式匹配,~ 为区分大小写匹配,~* 为不区分大小写匹配,!~ , !~*前面两者的非操作

示例:

if ($request_uri ~ “^/breaktest$”) {

#测试链接http://192.168.88.38/breaktest,最终返回http200

return 200;

}

3.4.检查文件是否存在,-f存在即为true,!-f不存在即为true

3.5.检查目录是否存在,-d存在即为true,!-d不存在即为true

3.6.检查文件或目录是否存在,-e存在即为true,!-e不存在即为true

3.7.检查文件是否可执行,-x可执行即为true,!-x不可执行即为true

示例:

if (-e /usr/local/nginx/conf) {

return 200;

}

其他示例:

if ($http_user_agent ~ MSIE) {

rewrite ^(.*)$ /msie/$1 break;

} //如果UA包含"MSIE",rewrite请求到/msid/目录下

if ($http_cookie ~* "id=([^;]+)(?:;|$)") {

set $id $1;

} //如果cookie匹配正则,设置变量$id等于正则引用部分

if ($request_method = POST) {

return 405;

} //如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302

if ($slow) {

limit_rate 10k;

} //限速,$slow可以通过 set 指令设置

if (!-f $request_filename){

break;

proxy_pass http://127.0.0.1;

} //如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查

if ($args ~ post=140){

rewrite ^ http://mysite.com/ permanent;

} //如果query string中包含"post=140",永久重定向到http://mysite.com

  1. if指令中,可以使用全局变量,这些变量有:
  2. $ args: #这个变量等于请求行中的参数,同$query_string
  3. $ content_length: 请求头中的Content-length字段。
  4. $content_type: 请求头中的Content-Type字段。
  5. $document_root: 当前请求在root指令中指定的值。
  6. $host: 请求主机头字段,否则为服务器名称。
  7. $http_user_agent: 客户端agent信息
  8. $http_cookie: 客户端cookie信息
  9. $limit_rate: 这个变量可以限制连接速率。
  10. $request_method: 客户端请求的动作,通常为GET或POST。
  11. $remote_addr: 客户端的IP地址。
  12. $remote_port: 客户端的端口。
  13. $remote_user: 已经经过Auth Basic Module验证的用户名。
  14. $request_filename: 当前请求的文件路径,由root或alias指令与URI请求生成。
  15. $scheme: HTTP协议(如http,https)。
  16. $server_protocol: 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
  17. $server_addr: 服务器地址,在完成一次系统调用后可以确定这个值。
  18. $server_name: 服务器名称。
  19. $server_port: 请求到达服务器的端口号。
  20. $request_uri: 包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz”。
  21. $ uri: 不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html”。
  22. $ document_uri: 与$uri相同。

4.return

配置位置:server,location,if

参数值:return code [text]返回状态码及文本、return url重定向、return code url重定向

5.rewrite

配置位置:server,location,if

参数值:rewrite regex replacement [flag],用于以正则表达式匹配特定格式的url并重写url.

regex为正则表达式,replacement为重写的内容,flag为rewrite的标识位

replacement:重写的url带http,表示重定向

示例:

location / {

#测试链接http://192.168.88.38/test/,被重定向到百度首页,后面的语句不会再执行

rewrite /test/(.*) http://www.baidu.com;

set $set_value_test "112233 $request_uri";

return 200 $set_value_test;

}

replacement:重写的url不带http,单纯的重写url

示例:

location / {

#测试链接http://192.168.88.38/test/,匹配到location /{}后url被重写为http://192.168.88.38/breaktest,继续搜索匹配

#匹配到location = /breaktest{},最终返回http200及this is breaktest

rewrite /test/(.*) /breaktest;

}

location = /breaktest {

return 200 "this is breaktest";

}

6、flag

flag:用于设置重写url后的进一步操作,有break,last,redirect,permanent,rewrite不带flag时,多个rewrite指令顺序执行,当location中没有可执行的rewrite模块指令时,重新发起一次location匹配,下面说明各个flag的用途:

break:和上面讲的break用途及用法一样,终止执行rewrite模块指令集;

last:终止执行rewrite模块指令集,并开始搜寻重写url后匹配的location;

redirect:临时重定向

permanent:永久重定向

示例:

location / {

#测试链接http://192.168.88.38/test1,匹配到location / {}

rewrite ^/test1 /test2;#被重写为/test2,继续往下执行rewrite

rewrite ^/test2 /test3;#被重写为/test3,往下没有可执行的rewrite模块指令,发起一次location匹配,匹配到location /test3 {},最终返回http200及/test3

}

location /test2 {

return 200 "/test2";

}

location /test3 {

return 200 "/test3";

}

last和break的区别在于,last会发起新的location匹配,而break不会。

示例:

location / {

rewrite ^/test1 /test2;

rewrite ^/test2 /test3 last;

rewrite ^/test3 /test4;

}

location /test2 {

return 200 "/test2";

}

location /test3 {

return 200 "/test3";

}

location /test4 {

return 200 "/test4";

}

测试链接:http://192.168.88.38/test1 匹配到 location / {}后,被重写为/test2,顺序执行再次被重写为/test3,因为flag为last,所以不会继续重写为/test4,而是发起一次location匹配,匹配到location /test3{},所以最终返回结果为http200及/test3;

如果把location /{}中的last改为break,被重写为/test3后,不再重写为/test4,也不会发起location,最终没有可匹配的资源,返回http404。

7、正则匹配URL的参数传递

小括号()之间匹配的内容,可以在后面通过 $下标 来引用,如1 表 示 引 用 第 一 个 小 括 号 匹 配 的 内 容 , 1表示引用第一个小括号匹配的内容,1表示引用第一个小括号匹配的内容,表示引用第二个小括号匹配的内容。

示例:

location / {

rewrite ^/(test1)/(test2)/(test3) /$2/$3;

return 200 $2-$3;

}

最终返回结果:

[转帖]详解nginx的rewrite应用,Nginx高级之Rewrite规则的更多相关文章

  1. [推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆)

    原文:[推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆) [推荐]ORACLE PL/SQL编程详解之三: PL/SQL流程控制语句(不给规则,不成方圆) ...

  2. nginx详解(代理服务器的解释+nginx 在linux 下的安装+nginx.conf 中的配置解释)

    一.概论 1.什么是代理服务器 代理服务器,客户机在发送请求时,不会直接发送给目的主机,而是先发送给代理服务器,代理服务接受客户机请求之后,再向主机发出,并接收目的主机返回的数据,存放在代理服务器的硬 ...

  3. vagrant(二)配置文件vagrantfile详解 以及安装php、nginx、mysql

    上一篇文章完整的讲叙了如何安装一个vagrant的环境.这里主要说一说vagrant的配置文件Vagrantfile. 一 配置详解 在我们的开发目录下有一个文件Vagrantfile,里面包含有大量 ...

  4. [转帖]详解oracle数据库唯一主键SYS_GUID()

    详解oracle数据库唯一主键SYS_GUID() https://www.toutiao.com/i6728736163407856139/ 其实 需要注意 这里满不能截取 因为截取了 就不一定唯一 ...

  5. [转帖]详解Linux系统inode原理--硬链接、软链接、innodb大小和划分等

    详解Linux系统inode原理--硬链接.软链接.innodb大小和划分等 原创 波波说运维 2019-07-17 00:03:00 https://www.toutiao.com/i6713116 ...

  6. [转帖]详解shell脚本括号区别--$()、$「 」、$「 」 、$(()) 、「 」 、「[ 」]

    详解shell脚本括号区别--$().$「 」.$「 」 .$(()) .「 」 .「[ 」] 原创 波波说运维 2019-07-31 00:01:00 https://www.toutiao.com ...

  7. 多测师讲解自动化测试 _RF课堂_定位详解(002上午)_高级讲师肖sir

    1,打开克览器 2.id定位 Input Text id=kw 我是id定位 #id定位方法 3.name定位 Input Text name=wd 我是name定位方法 #我是name定位方法 4. ...

  8. Nginx详解二十八:Nginx架构篇Nginx+Lua的安全waf防火墙

    Nginx+Lua的安全waf防火墙 看一下别人写好的:https://github.com/loveshell/ngx_lua_waf 先安装git:yum -y install git 在/opt ...

  9. Nginx详解二十六:Nginx架构篇之性能优化

    一.性能优化考虑点 1.当前系统结构瓶颈 通过压力测试观察指标.日志检测.性能分析 2.了解业务模式 接口业务类型.系统层次化结构 3.性能与安全 二.ab接口压力测试工具 1.安装:yum -y i ...

  10. Nginx详解二十五:Nginx架构篇之Nginx常见的问题

    Nginx常见的问题 1.相同server_name多个虚拟主机优先级访问,是按读取文件的优先级来排序 在/opt/app/下准备3个code文件夹,下面放入3个html文件,里面的内容分别是code ...

随机推荐

  1. 文心一言 VS 讯飞星火 VS chatgpt (176)-- 算法导论13.3 5题

    五.用go语言,考虑一棵用 RB-INSERT 插人 n 个结点而成的红黑树.证明:如果 n>1,则该树至少有一个红结点. 文心一言: 要证明这个问题,我们首先需要理解红黑树的性质.红黑树是一种 ...

  2. 最后一天,CDMP数据治理认证高分训练营(9-10月)开放报名!

    大家好,我是独孤风,一位曾经的港口煤炭工人,目前在某国企任大数据负责人,公众号大数据流动主理人. 首先告诉大家一个好消息,在大家共同的努力下,我们的CDMP国际数据治理认证训练营(7-8月)基本收官, ...

  3. 火山引擎DataLeap的Data Catalog系统搜索实践 (上)

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 摘要 火山引擎大数据研发治理套件 DataLeap的Data Catalog系统通过汇总和组织各种元数据,解决了数 ...

  4. 音乐 APP 用户争夺战,火山引擎 VeDI 助力用户体验升级!

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,并进入官方交流群 国内数字音乐市场正在保持稳定增长. 根据华经产业研究院数据报告显示,2020 年数字音乐市场规模为 357.3 亿元,到 ...

  5. cxf 动态调用 WebService No compiler detected, make sure you are running on top of a JDK instead of a JRE

    WebService cxf No compiler detected, make sure you are running on top of a JDK instead of a JRE [202 ...

  6. MetaGPT day01: MetaGPT作者代码走读、软件公司初始示例

    LLM发展历史 - 2013年word2vec提出,但效果不好 - 2017年Transformer结构提出,降低网络复杂度 - 2018年BERT预训练语言模型效果显著提升 - 2019年GPT-3 ...

  7. Go--记录下踩map的坑

    这两天新调个接口的时候,一直提示签名错误,但所需的时间,工号,token都是对的,完全没有头绪,卡了两天后,终于找到原因了 原因是我的校验信息,是要将时间,工号,token封装在一起成字符串,然后用m ...

  8. ABAP使用异步远程RFC实现并行处理

    1.使用场景 当开发复杂报表,需要处理大量数据,不管怎么优化计算和查询语句,程序的运行效率还是达不到用户要求,怎么办? 为了解决这个问题,就需要程序实现并行处理. 本文档就是通过异步调用远程RFC的办 ...

  9. C++正则表达式的初步使用

    正则表达式(Regular Expressions),又被称为regex.regexp 或 RE,是一种十分简便.灵活的文本处理工具.它可以用来精确地找出某文本中匹配某种指定规则的内容.从C++11开 ...

  10. CodeCraft-21 and Codeforces Round #711 (Div. 2) A~C 个人题解

    补题链接:Here 1498A. GCD Sum 题意:给定一个 gcdSum 操作:\(gcdSum(762) = gcd(762,7 + 6 + 2) = gcd(762,15) = 3\) 请问 ...