目录
一 . 简介
Nginx 的重写功能是指通过修改请求 URL 的方式来实现URL重定向或者路由转发的功能。
Nginx通过 ngx_http_rewrite_module
模块来实现重写功能。
重写功能的重要作用
它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为自动访问,另外还可以在一定程度上提高网站的安全性。
二. if指令
Nginx 的 if
指令可以在配置中实现条件判断,可以配置在server或location块中。
2.1基本语法
if (条件匹配) {
action
}
使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false。
变量与表达式之间使用以下符号链接
= #比较变量和字符串是否相等,相等时if指令认为该条件为true,反之为false
!= #比较变量和字符串是否不相等,不相等时if指令认为条件为true,反之为false
~ #区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~ #区分大小写字符,判断是否匹配,不满足匹配条件为真,满足匹配条件为假
~* #不区分大小写字符,可以通过正则表达式匹配,满足匹配条件为真,不满足匹配条件为假
!~* #不区分大小字符,判断是否匹配,满足匹配条件为假,不满足匹配条件为真
-f 和 !-f #判断请求的文件是否存在和是否不存在
-d 和 !-d #判断请求的目录是否存在和是否不存在
-x 和 !-x #判断文件是否可执行和是否不可执行
-e 和 !-e #判断请求的文件或目录是否存在和是否不存在(包括文件,目录,软链接)
注意:
如果$变量的值为空字符串或0,则if指令认为该条件为false,其他条件为true。
nginx 1.0.1之前$变量的值如果以0开头的任意字符串会返回false。
2.2 举例说明
#想匹配 /blog/archive 后跟特定前缀year-
location /blog/archive {
rewrite ^/blog/archive/year-(.*)$ /blog/posts/year-$1 permanent;
}
访问 http://example.com/blog/archive/year-2023 会被重定向到 http://example.com/blog/posts/year-2023。
访问 http://example.com/blog/archive/month-10 不会被重定向。
2.3 配置实例
#确认/apps/nginx/html/test文件和目录存在
mkdir -p /apps/nginx/html/test
echo "Hello, this is /test" > /apps/nginx/html/test/index.html
#编辑主配置文件
vim /apps/nginx/conf/nginx.conf
location /test {
index index.html;
default_type text/html;
if ( $scheme = http ){
echo "if-----> $scheme";
}
#进行协议判断,是不是http
if (!-e $request_filename) {
echo "$request_filename is not exist";
}
#判断文件是否存在
/apps/nginx/sbin/nginx -t
/apps/nginx/sbin/nginx -s reload
三. return
3.1 基本语法
return用于完成对请求的处理,并直接向客户端返回响应状态码。
return code; #返回给客户端指定的HTTP状态码
return code [text]; #返回给客户端的状态码及响应报文的实体内容,可以调用变量,其中text如果有空格,需要用单或双引号
return code url; #返回给客户端的URL地址
301 客户机访问服务器时,服务器会将跳转缓存到客户机中,下次跳转就不需要服务器,从客户机本地缓存调取。
302 临时
3.2 配置实例
vim /apps/nginx/conf/nginx.conf
location /test {
index index.html;
default_type text/html;
if (!-e $request_filename) {
return 302 /index.html;
}
}
#访问一个不存在的文件
curl http://192.168.52.102/test/nonexistent -I
注意:if
指令在 Nginx 中具有以下副作用:
- 破坏
location
的上下文。 - 导致性能问题。
- 干扰其他指令。
- 导致难以调试的问题。
(所以配置实例只用了一个if)
四. set指令
set 指令用于创建或更改一个变量的值,即自定义变量。
4.1 基本语法
set $variable value;
$variable:变量名,必须以 $ 开头。
value:变量的值,可以是字符串、变量或表达式
4.2 举例说明
创建一个变量并赋予一个静态值:
set $my_var 'Hello, World!';
将已有的变量的值赋给新的变量
set $new_var $existing_var;
使用表达式给变量赋值
set $num 10;
set $result $num * 2;
4.3 配置实例
mkdir -p /apps/nginx/html/work
echo "Hello, this is /work" > /apps/nginx/html/work/index.html
#配置文件中修改
vim /apps/nginx/conf/nginx.conf
location /work {
root /data/nginx/html/pc;
index index.html;
default_type text/html;
set $name dhf;
echo $name;
}
curl 192.168.52.102/work
五.break指令
5.1 作用
break
指令用于中断当前请求的处理,并立即终止对该请求的后续处理过程。
-
当 Nginx 遇到 .break 指令时,会立即停止当前的重写规则处理,不再继续执行后续的重写规则。
-
break 会保留当前的重写结果,并将其作为最终的 URL,避免循环重写。
-
使用 break 可以避免重写规则进入无限循环。
5.2 举例说明
location /example {
if ($arg_param = "value") {
# 条件满足,中断请求处理
break;
}
# 继续处理请求...
}
5.3 配置实例
#配置文件中添加
location /work {
default_type text/html;
set $name "dhf";
echo $name;
break;
set $n_name "2025-5-10";
echo $n_name;
}
curl 192.168.52.102/work
六.rewrite指令
6.1 基本语法
rewrite regex replacement [flag];
regex:正则表达式,用于匹配请求的 URL。
replacement:替换后的 URL 或路径。
flag:可选参数,用于指定重写的行为。
regex 部分 (正则表达式)
. #匹配除换行符以外的任意字符
\w #匹配字母或数字或下划线或汉字
\s #匹配任意的空白符
\d #匹配数字 [0-9]
\b #匹配单词的开始或结束
^ #匹配字符串的开始
$ #匹配字符串的结束
* #匹配重复零次或更多次
+ #匹配重复一次或更多次
? #匹配重复零次或一次
{n} #匹配重复n次
{n,} #匹配重复n次或更多次
{n,m} #匹配重复n到m次
*? #匹配重复任意次,但尽可能少重复
+? #匹配重复1次或更多次,但尽可能少重复
?? #匹配重复0次或1次,但尽可能少重复
{n,m}? #匹配重复n到m次,但尽可能少重复
{n,}? #匹配重复n次以上,但尽可能少重复
\W #匹配任意不是字母,数字,下划线,汉字的字符
\S #匹配任意不是空白符的字符
\D #匹配任意非数字的字符
\B #匹配不是单词开头或结束的位置
[^x] #匹配除了x以外的任意字符
[^kgc] #匹配除了kgc 这几个字母以外的任意字符
常见的 flag 包括
last:停止处理当前 rewrite 指令,并重新匹配新的 URL。
break:停止处理当前 rewrite 指令,不再匹配其他规则。
redirect:返回 302 临时重定向。
permanent:返回 301 永久重定向。
6.2 配置实例
6.2.1 重写ULR路径
#修改主配置文件
vim /apps/nginx/conf/nginx.conf
#再location / 添加
rewrite ^/bj/(.*) /beijing/$1 permanent;
#建立测试文件夹和主页
cd /apps/nginx/html
mkdir bj ;echo This is bj > bj/index.html
mkdir beijing;echo This is Beijing > beijing/index.html
/apps/nginx/sbin/nginx -t
/apps/nginx/sbin/nginx -s reload
curl 192.168.52.102/bj -L
6.2.2 域名重定向
vim /apps/nginx/conf/nginx.conf
server {
listen 80;
server_name localhost;
root /apps/nginx/html;
location / {
rewrite / https://www.baidu.com permanent;
}
}
/apps/nginx/sbin/nginx -t
/apps/nginx/sbin/nginx -s reload
6.2.3 http 转https
(详细过程同自签名证书)
vim /apps/nginx/conf/nginx.conf
server {
listen 443 ssl;
listen 80;
server_name www.kgc.org;
ssl_certificate /apps/nginx/certs/www.kgc.org.crt;
ssl_certificate_key /apps/nginx/certs/www.kgc.org.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;
}
}
location /login {
if ($scheme = http ){ #如果没有加条件判断,会导致死循环
rewrite / https://$host/login redirect;
}
}
}
# 创建证书目录(如果不存在)
mkdir -p /zs/
# 上传或生成证书文件到 /zs/
# cp your_cert.crt /zs/www.kgc.com.crt
# cp your_key.key /zs/www.kgc.com.key
# 创建网站根目录及默认页面
mkdir -p /data/nginx/html/pc/
echo "<h1>Welcome to www.dhf.com</h1>" | sudo tee /data/nginx/html/pc/index.html
# 设置权限(确保 Nginx 用户可读)
chown -R nginx:nginx /data/nginx/html/ /zs/
chmod 600 /zs/www.kgc.com.key # 私钥必须严格限制权限
七. 防盗链
7.1 盗链的定义
指第三方网站通过(如<img>、<video>标签或文件链接)直接嵌入使用目标网站的服务器资源,导致目标服务器带宽、计算资源被无偿消耗。
7.2 防盗链的简介
在Nginx中实现防盗链主要通过验证HTTP请求的Referer
头,确保资源仅允许特定来源访问。
核心指令:valid_referers
#基础语法
valid_referers none | blocked | server_names | string ...;
none:允许无Referer的请求(如直接访问)。
blocked:允许Referer被防火墙或代理删除的请求。
server_names:允许来自指定域名的请求(支持通配符和正则)。
string:可自定义字符串,支配通配符、正则表达式写法。
7.3 实现盗链
实验步骤如下
需要两台虚拟机
centos7-13------->192.168.52.103
centos7-14------->192.168.52.104(被盗虚拟机)
1. 先进行安装
yum install -y epel-release
yum install nginx -y
systemctl start nginx
2. 进行配置
第一台虚拟机
cd /usr/share/nginx/html
vim index.html
<html>
<body>
<h1>this is yunjisuan </h1>
<img src="http://192.168.52.103/test.jpg"/>
</body>
</html>
nginx -t
systemctl restart nginx
第二台虚拟机(被盗的)
cd /usr/share/nginx/html
选择一张照片拖入虚拟机
#重命名照片为test.jpg
mv OIP-C.jpg test.jpg
7.4设置防盗链
vim /etc/nginx/conf.d/bbs.conf
server {
listen 80;
server_name localhost;
location ~* \.(jpg|gif|swf|png)$ {
root /usr/share/nginx/html;
valid_referers none blocked *.pc.com pc.com;
if ( $invalid_referer ) {
return 403;
}
}
}