一、Nginx Rewrite概述
简单的说就是重写客户端请求的URL,一般是在更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等场景起到作用。
1.1 Rewrite跳转场景
-
可以调整用户浏览的URL。
-
为了让搜索引擎好抓取及用户体验更好,会将动态URL地址伪装成静态地址提供服务。
-
网站更新域名后,为了确保旧的域名还能够访问网站,就需将旧域名重写为新域名。
-
根据特殊变量、目录、客户端的信息进行URL调整。
1.2 Rewrite实现跳转
Nginx是通过ngx_http_rewrite_module模块支持url重写、if条件判断,但不支持else,通过该模块可以用set指令在nginx的配置文件中创建变量并赋值。默认支持正则表达式匹配。根据相关变量重定向和选择不同的配置,从一个location跳到另一个location。这样的循环最多执行10次,超过会返回500状态码。
二、Nginx Rewrite基本操作
2.1 Rewrite语法
rewrite <regex> <replacement> [flag];
- regex表示需要写入正则表达式规则
- replacement表示跳转后的内容(URL)
- flag表示rewrite支持的flag标记
- last:表示完成rewrite。
- break:本条规则匹配完成后即终止,不再匹配后面的任何规则。
- redirect:默认的标记,返回302状态码,浏览器地址会显示跳转后的URL地址,爬虫程序不会更新url,之后仍会爬取原来url标识的资源(虽然原来的资源已经不存在)。
- permanent:返回301状态码,浏览器地址会显示跳转后的URL地址,爬虫会更新url,之后不会爬取原来url标识的资源。
关于flag标志last和break的区别是:last一般写在server和if中,而break一般使用在location中。last不终止重写后的url匹配,重写后的url还会再走一次匹配流程,有可能上一次匹配结果满足下一次匹配的条件,导致多次匹配;而break终止重写后的匹配。
2.2 location分类
大致可以分为三类:
- location = path {} [精准匹配]
- location path {} [一般匹配]
- location ~ path {} [正则匹配]
关于正则匹配的一些常用正则表达式:
~* | 表示执行一个正则匹配,不区分大小写 |
!~ | 表示执行一个正则匹配,区分大小写反向匹配 |
!~* | 表示执行一个正则匹配,不区分大小写反向匹配 |
^~ | 表示普通字符匹配。使用前缀匹配,匹配成功则不再匹配其他的location |
= | 进行普通字符精准匹配 |
@ | 定义一个命名的location,使用在内部定向时,如error_page,try_files。 |
2.3 Location优先级
匹配优先级和顺序无关,和location表达式的类型有关,相同类型的表达式,字符串长的会优先匹配。以下是按优先级排列说明:
- 等号类型的优先级最高。一旦匹配成功就不会再查找其他配置项。
- ^~类型表达式一旦匹配成功,就不会再查找其他配置项。
- 正则表达式类型(~和~*) 的优先级次之
- 常规字符串匹配类型,按前缀匹配。
- 通用匹配(/),如果没有其他匹配,任何请求都会匹配到。
对location优先级的匹配条件的分类:
- 如果是匹配某个具体文件
(location = 完整路径) > (location ^~ 完整路径) > (location ~* 完整路径) > (location ~ 完整路径) > (location 完整路径) > (location /)
- 如果是用目录做匹配访问某个文件
(location = 目录) > (location ^~ 目录) > (location ~* 目录) > (location ~ 目录) > (location 目录) > (location /)
rewrite和location似乎有些相像,其主要区别是rewrite是在同一域名内更改获取资源的路径,而location是对一类路径做访问控制和反向代理。它们的执行顺序如下:
server里的rewrite -> location -> location里的rewrite