rewrite功能:就是使用nginx提供的全局变量或自己设置的变量,结合正则表达式和标志位实现url重写以及重定向。
(1)flag标志位:
last #本条规则匹配完成后,继续向下匹配新的location URI规则
break #本条规则匹配完成即终止,不再匹配后面的任何规则
redirect #返回302临时重定向,浏览器地址会显示跳转后的URL地址
permanent #返回301永久重定向,浏览器地址栏会显示跳转后的URL地址
(2)rewrite 常用正则表达式说明
字符 |
描述 |
. |
匹配除换行符以外的任意字符 |
? |
匹配前面的字符零次或一次 |
+ |
匹配前面的字符一次或多次 |
* |
匹配前面的字符0次或多次 |
\d |
匹配一个数字字符。等价于[0-9] |
\ |
将后面接着的字符标记为一个特殊字符或一个原义字符或一个向后引用。如“\n”匹配一个换行符,而“\$”则匹配“$” |
^ |
匹配字符串的开始 |
$ |
匹配字符串的结尾 |
{n} |
匹配前面的字符n次 |
{n,} |
匹配前面的字符n次或更多次 |
[c] |
匹配单个字符c |
[a-z] |
匹配a-z小写字母的任意一个 |
小括号()之间匹配的内容,可以在后面通过$1来引用,$2表示的是前面第二个()里的内容。正则里面容易让人困惑的是\转义特殊字符。
rewrite ^/images/(.*)_(\d+)x(\d+)\.(png|jpg|gif)$ /resines/$1.$4?width=$2&height=$3? last;
#对形如/images/img_500x400.jpg的文件请求,重写到/resines/img.jpg?width=500&height=400地址,并会继续尝试匹配location。
i
(3)if判断指令语法
if (condition)
{...}
如果值为空或任何以0开头的字符串都会当做false
=或!= |
直接比较变量和内容 |
~ |
区分大小写正则表达式匹配 |
~* |
不区分大小写的正则表达式匹配 |
!~ |
区分大小写的正则表达式不匹配 |
-f和!-f |
用来判断文件是否存在 |
-d和!-d |
用来判断目录是否存在 |
-e和!-e |
用来判断文件或目录是否存在 |
-x和!-x |
用来判断文件是否可执行 |
#如果UA包含"MSIE",rewrite请求到/msid/目录下
if ($http_user_agent ~ MSIE) {
rewrite ^(.*)$ /msie/$1 break;
}
#如果cookie匹配正则,设置变量$id等于正则引用部分
if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
set $id $1;
}
#如果提交方法为POST,则返回状态405(Method not allowed)。return不能返回301,302
if ($request_method = POST) {
return 405;
}
#限速,$slow可以通过 set 指令设置
if ($slow) {
limit_rate 10k;
}
#如果请求的文件名不存在,则反向代理到localhost 。这里的break也是停止rewrite检查
if (!-f $request_filename){
break;
proxy_pass http://127.0.0.1;
}
#如果query string中包含"post=140",永久重定向到example.com
if ($args ~ post=140){
rewrite ^ http://resines.com/ permanent;
}
#防盗链
location ~* \.(gif|jpg|png|swf|flv)$ {
valid_referers none blocked www.resines.com www.resines.cn;
if ($invalid_referer) {
return 404;
}
}
(4)if判断可使用的全局变量
变量名称 |
变量说明 |
$args |
这个变量等于请求行中的参数,同$query_string |
$content_length |
请求头中的Content-length字段 |
$content_type |
请求头中的Content-Type字段 |
$document_root |
当前请求在root指令中指定的值 |
$host |
请求主机头字段,否则为服务器名称 |
$http_user_agent |
客户端agent信息 |
$http_cookie |
客户端cookie信息 |
$limit_rate |
这个变量可以限制连接速率 |
$request_method |
客户端请求的动作,通常为GET或POST |
$remote_addr |
客户端的IP地址 |
$remote_port |
客户端的端口 |
$remote_user |
已经经过Auth Basic Module验证的用户名 |
$request_filename |
当前请求的文件路径,由root或alias指令与URI请求生成 |
$scheme |
HTTP方法(如http,https) |
$server_protocol |
请求使用的协议,通常是HTTP/1.0或HTTP/1.1 |
$server_addr |
服务器地址,在完成一次系统调用后可以确定这个值 |
$server_name |
服务器名称 |
$server_port |
请求到达服务器的端口号 |
$request_uri |
包含请求参数的原始URI,不包含主机名,如:”/foo/bar.php?arg=baz” |
$uri |
不带请求参数的当前URI,$uri不包含主机名,如”/foo/bar.html” |
$document_uri |
与$uri相同 |
5、列举实例
1.阻止下载协议代理,命令如下:
##Block download agents##
if ($http_user_agent ~* LWP:Simple | BBBike | wget)
{
return 403;
}
#说明:如果用户匹配了if后面的客户端(例如wget),就返回403.
2.根据$http_user_agent获取客户端agent,然后判断是否允许或返回指定错误码。
添加内容防止N多爬虫代理访问网站,命令如下:
#这些爬虫代理使用“|”分隔,具体要处理的爬虫可以根据需求增加或减少,添加的内容如下:
if ($http_user_agent ~* "qihoobot|Baiduspider|Googlebot-Modile|Googlebot-Image|Mediapartners-Google|Adsbot-Google|Yahoo! SSlurp China|YoudaoBot|Sosospider|Sogou spider|Sogou web spider|MSNBot")
{
return 403;
}
3.测试禁止不同的浏览器软件访问
if ($http_user_agent ~* "Firefox|MSIE")
{
rewrite ^(.*) http://www.wk.com/$1 permanent;
}
#如果浏览器为Firefox或IE,就会跳转到http://www.wk.com
4.限制请求方式
#Only allow these request methods
if ($request_method ! ~ ^(GET|HEAD|POST)$)
{
return 501;
}
5.反向代理
upstream ngxin_http {
server 192.168.1.10:8080 weight=2 max_fails=3 fail_timeout=100s;
}
upstream nginx_url {
server 192.168.1.11:8080 weight=2 max_fails=3 fail_timeout=100s;
}
server {
listen 8000;
server_name huawei.com;
access_log "pipe:rollback /data/log/nginx/access.log interval=1d baknum=7 maxsize=1G" main;
location ^~/user/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
rewrite ^/user/(.*)$ /$1 break;
proxy_pass http://nginx_http/;
}
location ^~/order/ {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-NginX-Proxy true;
rewrite ^/order/(.*)$ /$1 break;
proxy_pass http://nginx_url/;
}
}