前言
Nginx Rewrite 从功能上看和 location 有点相似,都可以实现跳转,主要区别在于 rewrite 是在同一域,location是对一类路径做控制访问或者反向代理。
Rewrite 跳转场景
- 调整用户浏览的URL,使URL看起来更规范、合理,合乎开发及产品人员的需求。
- 为了让搜索引擎搜寻网站内容及用户体验更好,企业会将动态URL地址伪装成静态地址提供服务。
- 新旧域名的一个跳转,例如访问企业网站旧网址为www.old.com 会跳转到 www.new.com、
- 服务端某些业务的调整,比如根据特殊变量、目录、客户端的信息进行URL调整等。
Rewirte 跳转实现
- Nginx 通过 ngx_http_rewrite_module 模块支持URL重写、支持if条件判断,但不支持else。
- 从一个 location 跳转到另一个 location 最多可以循环10次,超过后nginx会返回500错误。
- Rewirte使用Nginx全局变量或自己设置的变量(set 指令),结合正则表达式和标志位实现URL重写及重定向。
Rewrite 实际场景
- Nginx 实现跳转的三种方式
- ①使用rewirte进行匹配跳转
- ②使用if匹配全局变量后跳转
- ③使用location匹配在跳转
- rewrite 生效位置
- server{}中
- if{}中
- location{}中
- location中最对域名后边的除去传递参数外的字符串其作用。
- 对域名或参数字符串
- 使用if全局变量匹配
- 使用proxy_pass反向代理
常用的正则表达式元字符
元字符 |
说明 |
^ |
匹配以某个字符串为起始位置 |
$ |
匹配以某个字符串为结束位置 |
* |
匹配前面的字符0次或多次 |
+ |
匹配前面的字符1次或多次(至少1次) |
? |
匹配前面的字符串0次或1次 |
. |
匹配除“\n”之外的任何单个字符(除换行以外的单个字符) |
\ |
将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用 |
\d |
匹配纯数字 |
\w |
匹配字母或数字或下划线或汉字 |
\s |
匹配任意的空白符 |
\b |
匹配单词的开始或结束 |
{n} |
重复n次 |
{n,} |
重复n次或更多次(最少n次) |
[x] |
匹配单个字符x |
[a-z] |
匹配a-z小写字母的任意一个 |
[a-zA-z] |
匹配小写字母大写字母中的任意一个 |
Rewrite 命令语法
- rewrite <regex> <replacement> [flag];
- regex:正则表达式
- replacement:跳转后的内容
- rewrite支持的flag标记
flag标记说明
标记 |
说明 |
last |
相当于Apache的[L] 标记,表示完成rewrite |
break |
本条规则匹配完成即终止,不在匹配后面的任何规则 |
redirect |
返回302临时重定向,浏览器地址会显示跳转后的URL地址,爬虫不会更新URL |
permanent |
返回301永久重定向,浏览器地址栏会显示跳转后的URL地址,爬虫更新URL |
注意:last 和 break 的比较
- break:终止当前location的rewrite检测,而且不再进行location匹配。
- last:终止当前location的rewrite检测,但会继续重试location匹配并处理区块中的rewrite规则。
Rewrite 执行优先级
http{
server{
rewrite #第一优先级
location ~* \.(jpg|gif|swf){
rewrite #第二优先级
......
if( ......){
rewrite #第三优先级
}
}
}
}
Location常用的匹配规则
标记 |
说明 |
= |
普通字符串精确匹配 |
~ |
区分大小写的匹配 |
~* |
不区分大小写的匹配 |
!~ |
区分大小写的匹配取反 |
!~* |
不区分大小写匹配的取反 |
@ |
定义一个location,使用在内部定向的时候 |
Location优先级
- 相同类型的表达式,字符串长的会优先匹配
- 按优先级排列
- = 类型(精确匹配)
- ^~ 类型表达式(带正则的前缀匹配)
- 正则表达式(~和~*)类型
- 如果匹配的是文件 ~* 优先级高于 ~
- 如果匹配的是目录 ~ 优先级高于 ~*
- 通用匹配(/),也就是匹配根
- 匹配某个具体文件:(location = 完整路径 )→(location ^~ 完整路径)→(location ~* 完整路径)→(location ~ 完整路径)→(location 完整路径)→(location /)
- 匹配某个具体目录:(location = 目录 )→(location ^~ 目录)→(location ~ 目录)→(location ~* 目录)→(location 目录)→(location /)
Nginx 常用全局变量
$remote_addr // 获取客户端ip
$binary_remote_addr // 客户端ip(二进制)
$remote_port // 客户端port,如:50472
$remote_user // 已经经过Auth Basic Module验证的用户名
$host // 请求主机头字段,否则为服务器名称,如:blog.sakmon.com
$request // 用户请求信息,如:GET ?a=1&b=2 HTTP/1.1
$request_filename // 当前请求的文件的路径名,由root或alias和URI request组合而成,如:/2013/81.html
$status // 请求的响应状态码,如:200
$body_bytes_sent // 响应时送出的body字节数数量。即使连接中断,这个数据也是精确的,如:40
$content_length // 等于请求行的“Content_Length”的值
$content_type // 等于请求行的“Content_Type”的值
$http_referer