1、简介
Rewrite是Nginx服务器提供的一个重要基本功能,是Web服务器产品中几乎必备的功能。主要的作用是用来实现URL的重写。
注意: Nginx服务器的Rewrite功能的实现依赖于PCRE的支持,因此在编译安装Nginx服务器之前,需要安装PCRE库。Nginx使用的是ngx_http_rewrite_module模块来解析和处理Rewrite功能的相关配置
Rewrite的相关指令
set 指令
if 指令
break 指令
return 指令
rewrite 指令
rewrite_log 指令
Rewrite 的 应用场景
域名跳转
域名镜像
独立域名
目录自动添加 '/'
合并目录
防盗链的实现
2、set 指令
该指令用来设置一个新的变量。
语法 set $variable value;
默认值 -
位置 server、location、if
variable: 变量的名称、该变量名称要用 ‘$’ 作为变量的第一个字符,且不要与Nginx服务器预设的全局变量同名
value:变量的值,可以是字符串、其他变量或者变量的组合等
配置实例
配置结果
3、Rewrite 常用全局变量
变量 说明
$args 变量中存放了请求URL中的请求参数,比如 http://192.168.200.133/server?arg1=value&arg2=value2
中的'arg1=value1&arg2=value2',功能和query_string一样
$http_user_agent 变量存储的是用户访问服务的代理信息(如果通过浏览器访问,记录的是浏览器的相关版本信息)
$host 变量存储的是访问服务器的server_name值
$document_uri 变量存储的是当前访问地址的URI。比如 http:192.168.200.133/server?id=10&name=zhangsan中的'/server',
功能和$uri一样
$document_root 变量存储的是当前请求对应location的root值,如果未设置,默认指向Nginx自带html目录所在位置
$content_length 变量存储的是请求头中的Content-Length的值
$content_type 变量存储的是请求头中的Content-Type的值
$http_cookie 变量存储的是客户端的cookie信息,可以通过add_header Set-Cookie 'cookieName=cookieValue' 来添加cookie数据
$limit_rate 变量中存储的是Nginx服务器对网络连接速率的限制,也就是Nginx配置中对limit_rate指令设置的值,默认是0,不限制。
$remote_addr 变量中存储的是客户端的IP地址
$remote_port 变量中存储了客户端与服务端建立连接的口号
$remote_user 变量中存储了客户端的用户名,需要有认证模块才能获取
$scheme 变量中存储了访问协议
$server_addr 变量中存储了服务端的地址
$server_name 变量中存储了客户端请求到达服务器的名称
$server_port 变量中存储了客户端请求到达服务器的端口号
$server_protocol 变量中存储了客户端请求协议的版本,比如 'HTTP/1.1'
$request_body_file 变量中存储了发给后端服务器的本地文件资源的名称
$request_method 变量中存储了客户端的请求方式,比如 'GET','POST'
$request_filename 变量中存储了当前请求的资源文件的路径名
$request_uri 变量中存储了当前请求的URI,并且携带请求参数,比如http://192.168.200.133/server?id=10&name=zhangsan中的
'server?id=10&name=zhangsan'
上述参数还可以在日志文件中使用,这个就要用到前面我们介绍的log_format 指令
log_format main '$remote_addr - $request - $status-$request_uri $http_user_agent';
access_log logs/access.log main;
日志格式配置
输出的格式
$args 配置实例
$http_user_agent
4、if指令
该指令用来支持条件判断,并根据条件判断结果选择不同的Nginx配置。
语法 if (condition){......}
默认值 -
位置 server、location
condition为判定条件,可以支持以下写法:
4.1. 变量名。如果变量名对应的值为空字符串或’0’,if都判断为false,其他条件为true
if ($param) {}
此处 $username 为空,返回 param is empty
$username 不为空,返回的是ROSE的值
$args 获取 url后面的参数,不为空 返回success,为空返回error
4.2 使用 ‘=’ 和 ‘!=’ 比较变量和字符串是否相等,满足条件为true,不满足为false
if ($request_method = POST) {
return 405;
}
注意: 此处和JAVA不太一样的地方是字符串不需要添加引号,并且等号和不等号前后都需要加空格。
url后面没有携带参数,所以 if (
a
r
g
s
)
为
f
a
l
s
e
,
因为
g
e
t
请求所以
i
f
(
args) 为 false, 因为get 请求 所以 if(
args)为false,因为get请求所以if(request_method = POST ) 为false, 最后返回error
通过 curl post调用 接口 返回 405
4.3 使用正则表达式对变量进行匹配,匹配成功返回true,否则返回false。
变量和正则表达式之间使用 以下符号来连接。
'~' 代表匹配正则表达式过程中区分大小写,匹配成功返回true,匹配失败返回false
'~*' 代表匹配正则表达式过程中不区分大小写,,匹配成功返回true,匹配失败返回false
'!~' 和 '!~*' 刚好和上面取值相反,如果匹配上返回false,匹配不上返回true,匹配成功返回false,匹配失败返回true
注意:正则表达式一般不需要加引号,但是如果字符串中包含 ‘}’ 或者是 ‘;’ 等字符时,就需要把引号加上
。
$http_user_agent 中是否包含 Safari 包含 则返回 Chrome,不包含 返回error
4.4 判断请求的文件是否存在使用 ‘-f’ 和 ‘!-f’,
if (-f $request_filename) {
# 判断请求的文件是否存在
}
if (! -f $request_filename) {
#判断请求的文件是否不存在
}
$request_filename 为要访问的静态资源
判断请求的目录是否存在使用 ‘-d’ 和 ‘!d’
判断请求的目录或者文件是否存在 使用 ‘-e’ 和 ‘!-e’
判断请求的文件是否可执行 使用 ‘-x’ 和 ‘!-x’
5、break指令
该指令用于中断当前相同作用域中的其他Nginx配置。与该指令处于同一作用域的Nginx配置中,位于它前面的指令配置生效,位于后面的指令配置无效。并且break还有另外一个功能就是终止当前的匹配并把当前的URI在本location进行重定向访问处理。
语法 break;
默认值 -
位置 server、location、if
location /testbreak {
default_type text/plain;
set $username Tom;
if ($args) {
set $username JERRY;
break;
set $username ROSE;
}
add_header username $username;
return 200 $username;
}
不带args参数时
带$args参数时
走到break时 if 作用域 break后面的 参数配置无效,if 作用域外的参数会继续生效,但是会进行重定向处理,所以返回值不走 该return 200 $username,而是走默认配置下面的 html/testbreak/index.html,如果重定向没有其他额外配置时,就会走默认配置
{root html;
index index.html index.htm;}
如果此时 html下面没有 /testbreak/index.html就会报错
6、return 指令
该指令用于完成对请求的处理,直接向客户端返回。在return后的所有Nginx配置都是无效的
语法 return code [text];
return code URL;
return URL;
默认值 -
位置 server、location、if
code: 为返回给客户端的HTTP状态代理。可以返回的状态代码为0~999的任意HTTP状态代理
text: 为返回给客户端的响应内容,支持变量的使用
URL: 为返回给客户端的URL地址
location /testreturn {
retrun 200 success;
}
返回URL,重定向
访问 192.168.200.133:8081 时,直接重定向到百度的链接
7、rewrite指令
7.1 rewrite
该指令通过正则表达式的使用来改变URI。可以同时存在一个或者多个指令、按照顺序依次对URL进行匹配和处理。
作用是 匹配成功 URI后,然后重写URI
语法 rewrite regex replacement[flag];
默认值 -
位置 server、location、if
regex: 用来匹配URI的正则表达式
replacement: 匹配成功后,用于替换URI中被截取内容的字符串。如果该字符串是以 ‘http://’ 或者 'https://'开头的,则不会就行向下对URI进行其他处理,而是直接返回重写后的URI给客户端。
配置如下:
rewrite ^/rewrite/url\w*$ https://www.baidu.com;
表示匹配 http://ip:port/rewrite/url* 如果匹配到该url了,那么就重定向到百度
rewrite ^/rewrite/(test)\w*$ /$1;
$1表示获取第一个括号内的值也就是 test 所以 /$1 表示重定向到 /test 的url
rewrite ^/rewrite/(demo)\w*$ /$1; 表示重定向到 /demo 的url
下面的网址会匹配到第一个rewrite,所以会重定向到 baidu.com
下面的网址匹配到第二个url,所以重定向到 test_success
匹配第三个网址,重定向到 /demo
7.2 flag: 用来设置rewrite对URI的处理行为,可选值有如下:
7.2.1 last
终止继续在本location块中处理接收到的URI,并将此处重写的URI作为一个新的URI,使用各location块进行处理。该标志将重写后的URI重写在server中执行,在整个location块中去匹配URL执行,为重写后的URI提供了转入到其他location块的机会
匹配到 rewrite/(test) url 然后 重写url为 /test 搜寻到
location /test {
} 模块的值
7.2.2 break
将此处重写的URI作为一个新的URI,在本块中继续处理。该标志重写后的地址在当前的location块中执行,不会将新的URI转向其他的location块。
此时会报错,因为匹配到对应的url后,重写的url 为 /test 但是 只能在本location模块搜寻,不能匹配其他的location模块,但是本location模块,默认是返回 /html/test/index.html 这个文件,因为没有这个文件所以会报错
7.2.3 redict
将重写后的URI返回给客户端,状态码为302,指明临时重定向URI,主要用在replacement变量不是以‘http://’ 或者 ‘https://’ 开头的情况
/testabc 重定向到 /test
7.2.4 permanent
将重写后的URI返回给客户端,状态码为301,指明是永久重定向URI,主要用在replacement 变量不是以’http://’ 或者 'https//'开头的情况。
如果重定向的地址是过渡临时要用的,那么就写 redirect 临时重定向,如果是永久要用的,就写permanent
7.3 rewrite_log 指令
该指令配置是否开启URL重写日志的输出功能。
语法 rewrite_log on|off ;
默认值 rewrite_log off;
位置 http、server、location、if
开启后,URL重写的相关日志将以notice级别输出到error_log指令配置的日志文件汇总。
rewrite_log on;
error_log logs/error.log notice;
配置如下:
结果如下