Nginx 服务器利用 ngx_http_rewrite_module 模块解析和处理 rewrite 请求。
此功能依靠 PCRE(perl compatible regular expression)
,因此编译之前要安装 PCRE 库,rewrite 是 Nginx 服务器的重要功能之 一,用于实现 URL 的重写,URL 的重写是非常有用的功能,例如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为访问,还可以在一定程度上提高网站的安全性。
1. 模块指令
1.1 if 指令
用于条件匹配判断,并根据条件判断结果选择不同的 Nginx 配置,可以配置在 server 或 location 域中,if 语法仅能使用 if 做单次判断,不支持使用 if else 或者 if elif 这样的多重判断。
if (条件判断) {
action
}
=: 比较变量和字符串是否相等
!: 判断结果取反
!=: 比较变量和字符串是否不相等
~: 区分大小写字符,可以通过正则表达式匹配
~*: 不区分大小写字符,可以通过正则表达式匹配
-f: 判断请求的文件是否存在
-d: 判断请求的目录是否存在
-x: 判断文件是否可执行
-e: 判断请求的文件或目录是否存在(包括文件,目录,软链接)
范例:
location /main {
index index.html;
default_type text/html;
if ( $scheme = http ){
echo "if-----> $scheme";
}
if ( $scheme = https ){
echo "if ----> $scheme";
}
#if (-f $request_filename) {
# echo "$request_filename is exist";
#}
if (!-e $request_filename) {
echo "$request_filename is not exist";
#return 409;
}
}
1.2 set 指令
用于自定义变量,变量可以调用 Nginx 内置变量赋值给key,定义格式为 set $key value
,value 可以是 text 或 variables 或两者的组合。
注意:set 指令创建的变量是 Nginx 配置全局域可用的,但变量值只有在该变量赋值操作的 HTTP 处理流程中可用。
location /main {
root /data/nginx/html/pc;
index index.html;
default_type text/html;
set $name wuvikr;
echo $name;
set $my_port $server_port;
echo $my_port;
}
1.3 break 指令
用于中断当前相同作用域 location 中的其他 Nginx 配置,与该指令处于同一作用域的 Nginx 配置中,位于它前面的配置生效,位于后面的ngx_http_rewrite_module 模块中指令就不再执行,Nginx 服务器在根据配置处理请求的过程中遇到该指令的时候,回到上一层作用域继续向下读取配置,该指令可以在 server,location 和 if 域中使用。
注意:如果 break 指令在 location 块中,后续指令还会继续执行,只是不执行 ngx_http_rewrite_module 模块的指令,其它指令还会执行。
location /main {
root /data/nginx/html/pc;
index index.html;
default_type text/html;
set $name magedu;
echo $name;
break; #location块中break后面指令还会执行
set $my_port $server_port;
}
1.4 return 指令
用于完成对请求的处理,并直接向客户端返回响应状态码,比如可以指定重定向URL(对于特殊重定向状态码,301/302等) 或者是指定提示文本内容(对于特殊状态码403/500等),处于此指令后的所有配置都将不被执行,return 可以在 server、if 和 location 域中进行配置。
return code; # 返回给客户端指定的 HTTP 状态码
return code [text]; # 返回给客户端的状态码及响应报文的实体内容,因为有文本内容,code 不可以是 30X,可以调用变量.
return code URL; # 如果该 URL 不是具有完整 scheme 标识的 URL,该 URL 会被添加到当前 URL 之后。
return URL; # 此时 code 默认是 302,URL 必须是有完整 scheme 标识的 URL。
server {
listen 80;
server_name www.wuvikr.top;
location / {
root /data/nginx/html/pc;
default_type text/html;
index index.html;
if ( $scheme = http ){
#return 666;
#return 666 "not allow http";
#return 302 www.wuvikr.top/test; # 错误配置,浏览器会去重新访问 www.wuvikr.top/www.wuvikr.top/test。
#return 302 test; # 正确配置,浏览器会去重新访问 www.wuvikr.top/test。
#return 302 http://www.wuvikr.top/test; # 正确配置,浏览器会去重新访问 www.wuvikr.top/test。
#return http://www.wuvikr.top/test; # 正确配置,浏览器会去重新访问 www.wuvikr.top/test。
return test; # 错误配置,不写code 时,URL 必须是有完整 scheme 标识的 URL。
echo "if-----> $scheme"; # return 后面的将不再执行
}
if ( $scheme = https ){
echo "if ----> $scheme";
}
}
}
1.5 rewrite_log 指令
用于开启 rewrite 相关执行结果以 notice 级别日志记录到 error_log 日志文件当中,可以配置在 http、server、location 或 if 中。
location /main {
rewrite_log on;
error_log log/main-error.log notice;
}
1.5 rewrite 指令
对用户的 URI 用正则表达式的方式进行重写,并跳转到新的 URI。可以配置在 server、location、if 中。
语法格式如下:rewrite regex replacement [flag];
- regex 是 PCRE 语法格式的正则表达式;
- replacement 是重写 URI 的改写规则,注意:如果替换后的 URI 是以
**http://**
或**https://**
等 scheme 协议开头时,则 Nginx 重写该语句后会停止执行后续任务,直接以 302 重定向将 URI 返回给客户端。 flag 是执行该条重写指令后的操作控制符,操作控制符有以下 4 种:
- last:执行完当前重写规则跳转到新的 URI 后会优先跳出去匹配 location ,而不是继续向下匹配。
- break:执行完当前重写规则跳转到新的 URI 后不再执行后续的 rewrite 模块的其他指令。
- redirect:返回 302 响应状态码的临时重定向,返回重定向 URI 内容,但用户浏览器网址仍然是请求时的 URI。
- permanent:返回 301 响应状态码的永久重定向,返回重定向 URI 内容,用户浏览器网址是重定向后的 URI。
- 没有 flag:没有 flag 的情况下,rewrite 匹配完成后会继续在 location 中向下执行,直到 rewrite 模块指令全部执行完成。
1.5.1 案例一:HTTP 重写到 HTTPS
方式一:
server {
server_name www.wuvikr.com;
listen 80;
listen 443 ssl;
ssl_certificate /apps/nginx/certs/www.wuvikr.com.pem;
ssl_certificate_key /apps/nginx/certs/www.wuvikr.com.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
# 针对全站跳转
location / {
root /data/nginx/html/pc;
index index.html;
if ($scheme = http ){ # 如果没有加条件判断,可能会导致死循环
rewrite / https://$host redirect;
rewrite / https://$host redirect;
}
}
# 针对特定的URL进行跳转https
location /login {
if ($scheme = http ){
rewrite / https://$host/login redirect;
}
}
}
方式二: ```bash server { server_name www.wuvikr.com; listen 443 ssl; ssl_certificate /apps/nginx/certs/www.wuvikr.com.pem; ssl_certificate_key /apps/nginx/certs/www.wuvikr.com.key; ssl_session_cache shared:sslcache:20m; ssl_session_timeout 10m; … }
server { server_name www.wuvikr.com; listen 80; rewrite ^(.*)$ https://${host}$1? permanent; } ```