Nginx服务器利用 ngx_http_rewrite_module 模块解析和处理rewrite请求,此功能依靠 PCRE(perl compatible regular expression),因此编译之前要安装PCRE库,rewrite是nginx服务器的重要功能之
一,用于实现URL的重写,URL的重写是非常有用的功能,比如它可以在我们改变网站结构之后,不需要客户端修改原来的书签,也无需其他网站修改我们的链接,就可以设置为自动访问,另外还可以在一定程度上提高网站的安全性。
ngx_http_rewrite_module模块指令
官方文档: Module ngx_http_rewrite_module
if 指令
官方文档:
Module ngx_http_rewrite_module
- if指令可以配置在server或location块中
- if指令用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置
- Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断
- 使用正则表达式对变量进行匹配,匹配成功时if指令认为条件为true,否则认为false
用于条件匹配判断,并根据条件判断结果选择不同的Nginx配置,可以配置在server或location块中进行配置,Nginx的if语法仅能使用if做单次判断,不支持使用if else或者if elif这样的多重判断,用法如下:
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
return 指令
- return用于完成对请求的处理,并直接向客户端返回响应状态码
- return可以在server、location块和 if 进行配置
- 处于此指令后的所有配置都将不被执行
语法格式:
Syntax: return code [text]; //返回给客户端的状态码及响应报文的实体内容
return code URL; //返回给客户端的URL地址
return URL;
Default: —
Context: server, location, if
状态码 301 和 302
状态码 | 含义 | 区别 |
301 | 永久重定向 | 服务器不需要每次向客户提供新的url,客户访问过后会记录在自己的缓存中,即使nginx服务器死机,客户在一定时间内也可以继续跳转 |
302 | 临时重定向 | 没有缓存,服务器断开无法重定向 |
set 指令
- set定义格式为set $key value
- 指定key并给其定义一个变量,变量可以调用Nginx内置变量赋值给key
- value可以是text, variables和两者的组合
语法格式:
Syntax: set $variable value;
Default: —
Context: server, location, if
break 指令
- 用于中断 当前相同作用域(location)中的其他Nginx配置,与该指令处于同一作用域的Nginx配置中,位于它前面的配置生效,位于后面的 ngx_http_rewrite_module 模块中指令就不再执行。
语法格式:
Syntax: break;
Default: —
Context: server, location, if
rewrite 指令
- 通过正则表达式的匹配来改变URI,可以同时存在一个或多个指令,按照顺序依次对URI进行匹配,rewrite主要是针对用户请求的URL或者是URI做具体处理
语法格式:
Syntax: rewrite regex replacement [flag];
Default: —
Context: server, location, if
//正则匹配原始访问url 替代你想让客户访问的 标志 ()premanent301 redirect302 break last
flag 说明:
类型 | flag | 区别 |
跳转型 | redirect | 临时重定向302 |
| permanent | 永久重定向301 |
代理型 | break | 是立即终止匹配 使用该url进行匹配 |
| last | 停止本location中的匹配,开启新一轮的location匹配 |
- 跳转型指由客户端浏览器重新对新地址进行请求
- 代理型是在WEB服务器内部实现跳转
- break 和 last 是为了防止死循环使用的
防盗链
防盗链基于客户端携带的referer实现,referer是记录打开一个页面之前记录是从哪个页面跳转过来的标记信息,如果别人只链接了自己网站图片或某个单独的资源,而不是打开了网站的整个页面,这就是盗链,referer就是之前的那个网站域名,正常的referer信息有以下几种:
none:请求报文首部没有referer首部,比如用户直接在浏览器输入域名访问web网站,就没有referer信息。
blocked:请求报文有referer首部,但无有效值,比如为空。
server_names:referer首部中包含本主机名及即nginx 监听的server_name。
arbitrary_string:自定义指定字符串,但可使用 * 作通配符。示例:*.kgc.org 或 www.kgc.*
regular expression:被指定的正则表达式模式匹配到的字符串,要使用 ~ 开头,例如:~.*.kgc.com
location ~* \.(jpg|gif|swf)$ {
root /data/nginx/pc;
valid_referers none blocked *.pc.com pc.com;
if ( $invalid_referer ) {
rewrite ^/ http://www.pc.com/error.png;
#return 403
}
}
~* \.(jpg|gif|swf)$:这段正则表达式表示匹配不区分大小写,以.jpg 或.gif 或.swf 结尾的文件
Valid_referers:设置信任的网站,可以正常使用图片。
None :浏览器中 referer 为空的情况,就是直接在浏览器访问图片。
Blocked :referer 不为空的情况 ,但是值被代理或防火墙删除了,这些值不以 http://或https://开头。后面的网址或者域名:referer 中包含相关字符串的网址。
If 语句:如果链接的来源域名不在 valid_referers 所列出的列表中,$invalid_referer 为1,则执行后面的操作,即进行重写或返回 403 页面。
实际操作
#机器一
server {
listen 80;
server_name www.cc.com;
root /data/html;
index index.html;
location ~* \.(jpg|gif|swfjepg|bmp)$ {
#访问时已上面这些结尾时跳转到/data/html/tp文件夹下
root /data/html/tp;
}
}
#在/data/html/tp站点下加入一张测试图片a.jpg
#盗图机器二
需要在/etc/hosts文件下加入www.cc.com的域名解析
#设置盗图机器的主站点
server {
listen 80;
server_name www.dao.com;
root /data/;
}
#在主站点下写一个index.html文件
vim index.html
<html>
<body>
<h1>this is daotu </h1>
<img src="http://www.cc.com/a.jpg"/>
</body>
</html>