1.Nginx Rewrite 概述
现在 Nginx 已经成为很多公司作为前端反向代理服务器的首选,在实际工作中往往会遇到很多跳转(重写 URL)的需求。比如:更换域名后需要保持旧的域名能跳转到新的域名上、某网页发生改变需要跳转到新的页面、网站防盗链等等需求。如果在后端使用的Apache 服务器,虽然也能做跳转,规则库也很强大,但是用 Nginx 跳转效率会更高。
1.Rewrite 跳转场景
Rewrite 跳转场景主要包括以下几种:
- 可以调整用户浏览的 URL,看起来更规范,合乎开发及产品人员的需求。
- 为了让搜索引擎搜录网站内容及用户体验更好,企业会将动态URL地址伪装成静态地址提供服务。
- 网址换新域名后,让旧的访问跳转到新的域名上。
- 根据特殊变量、目录、客户端的信息进行 URL调整等。
2.Rewrite跳转实现
Nginx 是通过 ngx_http_rewrite_module 模块支持 url 重写、支持if条件判断,但不支持 else。另外该模块需要 PCRE 支持,应在编译 Nginx 时指定 PCRE 支持,默认已经安装。根据相关变量重定向和选择不同的配置,从一个location 跳转到另一个location,不过这样的循环最多可以执行 10 次,超过后 Nginx 将返回 500 错误。同时,重写模块包含 set 指令来创建新的变量并设其值,这在有些情景下非常有用的,如记录条件标识、传递参数到其他location、记录做了什么等等。rewrite 功能就是使用 Nginx 提供的全局变量或自己设置的变量,结合正则表达式和标志位实现 ur 重写以及重定向。
3.Rewrite实际应用场景
在实际工作的应用中,Nginx跳转需求有三种方式可实现。可以直接用rewrite 进行匹配跳转,也可以使用if匹配全局变量后跳转。另外,还可以使用location 匹配再跳转。所以rewrite 只能放在 server{}、f}、location{}配置段中。例如 location 只能对域名后边的除去传递的参数外的字符串起作用,例如 http:/www.kgc.com/index.php?id=1 只对fndex.php 重写。如果想对域名或参数字符串起作用,可以使用if全局变量匹配,也可以使用 proxy_pass反向代理。
4.Nginx正则表达式
字符 | 摘要 |
---|---|
^ | 匹配输入字符串的起始位置 |
$ | 匹配输入字符串的结束位置 |
* | 匹配前面的字符零次或多次。如“o!“”能匹配“o"及“ol”、“oll” |
+ | 匹配前面的字符一次或多次。如“ol+”能匹配“o!”及“o!”、“ol”,但不能匹配“o” |
? | 匹配前面的字符零次或一次,例如“do(es)?"能匹配“do"或者“does”,”?"等效于”{0,1}” |
. | 匹配除“n”之外的任何单个字符,若要匹配包括“n"在内的任意字符,请使用诸如“[.\n]”之类的模式 |
\ | 将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如“\n"匹配一个换行符,而“$"则匹配“$” |
\d | 匹配纯数字 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
[c] | 匹配单个字符c |
[a-z] | 匹配 a-z 小写字母的任意一个 |
[a-zA-Z] | 匹配 a-z 小写字母或 A-Z大写字母的任意一个 |
2.Nginx Rewrite基本操作
2.1 Rewrite语法
Rewrite 命令的语法如下所示,其中regex 表示正则匹配规则、replacement 表示跳转后的内容、fag 表示 rewrite 支持的 fag 标记。
rewrite<regex><replacement>[flag];
flag标记说明:
- last:相当于 Apache 的[L]标记,表示完成 rewrite。
- break:本条规则匹配完成即终止,不再匹配后面的任何规则。
- redirect:返回 302临时重定向,浏览器地址会显示跳转后的 URL地址,爬虫不会更新url(因为是临时)。
- permanent:返回 301永久重定向,浏览器地址栏会显示跳转后的 URL地址,爬虫更新 url。
如果后面不跟 fag 标记,那么默认是 302临时重定向。在实际工作场景中,还有另;种 return 指定。因为 301 和 302 不能简单的只返回状态码,还必须有重定向的 URL,这就是 return 指令无法返回 301 和 302 的原因。
last 和 break 区别是: last 一般写在 server 和if中,而 break 一般使用在 location 中。last 不终止重写后的 ur 匹配,即新的 ur 会再从 server 走一遍匹配流程,而 break 终止重写后的匹配。
2.2Location 分类
location 大致可以分为三类,语法如下:
location = patt {}[精准匹配]
location patt {}[一般匹配]
location ~ patt {}[正则匹配]
精准匹配和一般匹配不需要做详细的说明,主要是正则匹配。下面就是正则匹配的一些表达式,需要多加牢记。
- ~:表示执行一个正则匹配,区分大小写。
- ~*:表示执行一个正则匹配,不区分大小写。
- 》 !~:表示执行一个正则匹配,区分大小写不匹配。
- > !~*:表示执行一个正则匹配,不区分大小写不匹配。
- ^~:表示普通字符匹配。使用前缀匹配。如果匹配成功,则不再匹配其他 location。
- =:进行普通字符精确匹配,也就是完全匹配。
- @:它定义一个命名的 location,使用在内部定向时,例如 error_page, tny _files.
2.3:Location 优先级
在Nginx 的location 配置中location 的顺序没有太大关系。匹配优先级和location 表达式的类型有关: 相同类型的表达式,字符串长的会优先匹配。
- 等号类型( = ) 的优先级最高。一旦匹配成功, 则不再查找其他匹配项。
- ^~类型表达式。一旦匹配成功, 则不再查找其他匹配项。
- 正则表达式类型( ~和~* )的优先级次之。
- 常规字符串匹配类型。按前缀匹配。
- 通用匹配( /) ' 如果没有其它匹配, 任何请求都会匹配到。
从功能看rewrite 和location 似乎有点像, 都能实现跳转,主要区别在千rewrite 是在同一域名内更改获取资源的路径, 而location 是对一类路径做控制访问或反向代理,还可以proxy_pass 到其他机器。很多情况下rewrite 也会写在location 里, 它们的执行顺序如下:
(1) 执行server 块里面的rewrite 指令。
(2) 执行location 匹配。
(3) 执行选定的location 中的rewrite 指令。