Rewrite功能
# Rewrite功能
这是Nginx服务器提供的一个重要的基本功能,是WEB服务器产品中几乎必备的功能。主要作用是用来实现URL重写。 例如你输入 www.360buy.com 会自动跳转到 www.jd.com
# set指令
'描述' | '指令' |
---|---|
语法 | set $variable value; |
默认值 | - |
位置 | server、location、if |
server {
listen 8080;
server_name localhost;
location /server {
set $name Tommy;
set $age 18;
return 200 $name,$age;
}
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
由于Nginx中有全局变量,因此确保不要命名冲突。
# Rewrite常用全局变量
变量 | 说明 |
---|---|
$age | 存放了URL中的请求参数 |
$http_user_agent | 变量存储的是用户访问服务的代理信息,例如访问的浏览器信息 |
$host | 服务器的server_name |
$document_uri | 存储了当前访问地址的URI |
其余变量查看: https://www.javatpoint.com/nginx-variables
# 这些变量能做什么?
- 设置管理日志,记录访问信息
http{
...
log_format main '$remote_addr - $request - $status - $request_uri - $http_user_agent';
server{
...
location /server {
access_log logs/access.log main;
...
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
# if指令
'' | '' |
---|---|
语法 | if (condition){...} |
默认值 | - |
位置 | server、location |
两种基本用法
if ($params){
...
}
if ($request_method = POST){
return 405;
}
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
正则表达式匹配 "~"代表匹配正则表达式过程中区分大小写 "~*"代表匹配正则表达式过程中不区分大小写 "!~"和"!~*"刚好和上面取相反之,如果匹配上返回false反之true
if ($http_user_agent ~ MSIE){
# $http_user_agent的值中是否包含MSIE字符串,如果包含返回True
}
1
2
3
2
3
判断文件是否存在 "-f"和"!-f" 文件 "-d"和"!-d" 目录 "-e"和"!-e" 文件/目录 "-x"和"!-x" 判断文件是否可执行
if (-f $request_filename){
#判断请求的文件是否存在
}
if (!-f $request_filename){
#判断请求文件是否不存在
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# rewrite指令
该指令通过正则表达式的使用来改变URI,可以同时存在一个或者多个指令,按照顺序依次对URL进行匹配和处理。
'' | '' |
---|---|
语法 | rewrite regex replacement [flag] |
默认值 | - |
位置 | server、location、if |
location /rewrite {
rewrite ^/rewrite/url\w*$ https://www.baidu.com
}
1
2
3
2
3
个人感觉这功能类似于其他web框架中的redirect+正则匹配的结合版。
可用参数:
- last - 将匹配的结果值作为新的正则验证值重新进入路由匹配。
- break - 将将匹配的结果值作为新的正则验证值重新进入当前的路由匹配
- redirect - 临时重定向
- permanent - 永久重定向
# 案例
# 多域名重定向
现在我有三个域名
- 主域名 www.tommy.com
- 副域名 www.cat.com
- 副域名 www.dog.com
我希望访问两个副域名时会自动跳转至主域名该如何实现?
server{
listen 80;
server_name www.cat.com www.dog.com;
#rewrite ^/ http://www.tommy.com;
rewrite ^(.*) http://www.tommy.com$1;
}
1
2
3
4
5
6
2
3
4
5
6
# 域名镜像
上面的案例中,我们实现了域名重定向,但无论如何访问cat和dog域名,都会直接跳转至tommy,此时我们希望能够在这两个副域名下的某个子目录资源做镜像,该如何实现呢?
server {
listen 80;
server_name www.cat.com www.dog.com;
#rewrite ^/ http://www.tommy.com;
#rewrite ^(.*) http://www.tommy.com$1;
location /user {
default_type text/plain;
return 200 "chengogn";
}
location / {
rewrite ^(.*) http://www.tommy.com$1;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
如你所见,其实就是把特定目录独立出来而已,其余的依旧是和上面一样。