Nginx之旅-Rewrite规则

rewrite规则作用

使用rewrite可以实现url重写以及对匹配的url重定向。

场景:

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

    页面跳转,兼容性支持,展示效果(避免长链接)等

  2. SEO优化

  3. 维护

    后台维护,流量转发等

  4. 安全(将动态请求伪装成静态请求)

内置的全局变量
变量名 描述
$args 这个变量等于请求行中的参数,同$query_string
$content_length 请求头中的Content-length字段
$content_type 请求头中的Content-Type字段
$document_root 当前请求在root指令中指定的值
$host 请求主机头字段,否则为服务器名称
$http_user_agent 客户端agent信息
$http_cookie 客户端cookie信息
$limit_rate 这个变量可以限制连接速率
$request_method 客户端请求的动作,通常为GET或POST
$remote_addr 客户端的IP地址
$remote_port 客户端的端口
$remote_user 已经经过Auth Basic Module验证的用户名
$request_filename 当前请求的文件路径,由root或alias指令与URI请求生成
$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相同
rewrite配置语法
1
2
3
Syntax:	rewrite regex replacement [flag];
Default: —
Context: server, location, if

If the specified regular expression matches a request URI, URI is changed as specified in the replacement string.

例子:配置所有的的请求到维护页面

1
rewrite ^(.*)$  /pages/maintain.html break;

😊这个知识点不错,可以在XX期间使用。

rewrite正则表达式
符号 含义
. 匹配除换行符外的
重复0次或1次
+ 重复1次或更多次
* 贪婪匹配,任意次
\d 匹配数字
^ 匹配字符串的开始
$ 匹配字符串的结束
{n} 重复n次
{n,} 重复n次或更多次
[c] 匹配单个字符
[a-z] 匹配a-z小写字母的任意一个
\ 转义字符
() 用于匹配括号之间的内容,通过$1,$2调用

if ($http_user_agent ~ MSIE){

rewrite ^(.*)$ /mise/$1 break}
rewrite规则中的flag

我们看下rewrite的一些规则

规则名 规则注释
last 停止
break 停止rewrite检测
redirect 返回302临时重定向,地址栏会显示跳转后的地址
permanent 返回301永久重定向,地址栏会显示跳转后的地址

permanent永久重定向,客户端在收到对应的请求后,除非清理缓存,否则请求将永久重定向到返回的URL。

redirect临时返回,客户端请求每次都是到服务端进行一次转发。

🌰

我们先看下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server {
listen 80;
server_name localhost;

access_log /var/log/nginx/host.access.log main;

root /opt/app/code;

location ~ ^/break {
rewrite ^/break /test/ break;
}

location ~ ^/last {
rewrite ^/last /test/ last;
}

location /test/ {
default_type application/json;
return 200 '{"status":"successs"}';
}
}

当直接访问/test/路径的时候返回

D4Ji79.png

当访问/break路径的时候

D4JKne.png

当访问/last的时候

D4JdBQ.png

为什么会出现上面的情况呢?

这是因为当匹配到breaklocation的时候回去家目录下(root目录)查找对应的访问路径是否存在,不会执行下面的location,但是我们没有创建对应的文件路径,因此就会报错。

当匹配到lastlocation的时候回再向下匹配,这时会匹配待/test对应的location所以能够正常返回(会重新请求一次)。

推荐阅读:

Nginx 中last和break 及 permanent 和 redirect

Nginx配置中last和break及permanent和redirect的区别

接着看下redirect的配置实例

1
2
3
4
location ~ ^/last {
# rewrite ^/last /test/ last;
rewrite ^/last /test/ redirect;
}

D4JHgK.png

D4Ye5n.png

发起了两次请求,第一次的请求返回的状态码是302,并且在返回头里制定了再次请求的Location

redirect 是客户端发起两次请求 last客户端只发起一次请求

看看redirectpermanent的区别:

1
2
3
4
location ~ ^/imooc {
# rewrite ^/imooc http://www.imooc.com/ permanent;
rewrite ^/imooc http://www.imooc.com/ redirect;
}

配置完之后访问/imooc之后会调到慕课网。然后关闭服务端的Nginx服务,再次访问的时候就不会跳转。

现在修改配置如下

1
2
3
4
location ~ ^/imooc {
# rewrite ^/imooc http://www.imooc.com/ permanent;
rewrite ^/imooc http://www.imooc.com/ redirect;
}

配置完之后访问/imooc之后会调到慕课网。然后关闭服务端的Nginx服务,再次访问的时候同样可以成功跳转到慕课网,然后清空浏览器数据,再次访问就会访问失败。

原因就是永久重定向浏览器会保存重定向结果,只要不清数据浏览器再次访问都是重定向的URL

rewrite规则场景

下面我们看下几个老师配置的重定向规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
location / {
rewrite ^/course-(\d+)-(\d+)-(\d+)\.html$ /course/$1/$2/course_$3.html;


if ($http_user_agent $* Chrome){
rewrite ^nginx https://www.baidu.com/ break;
}

if (!-f $request_filename){
rewrite ^/(.*)$ http://www.baidu.com/$1 redirect;
}

index index.html index.htm;
}

第二个是当客户端是Chrome的时候进行匹配。

第三个是请求一个文件路径,当文件路径不存在的情况下进行匹配。-f就是判断文件路径是否存在。

rewrite规则优先级

rewrite的规则在不同的上下文下,执行的优先级是不同的。

基本优先级是:执行server块的rewrite指令 –> 执行location匹配 –> 执行选定的location中的rewrite

优雅的Rewrite规则书写

DoGd81.png

DoGDKK.png

知识就是财富
如果您觉得文章对您有帮助, 欢迎请我喝杯水!