Rewrite 功能主要就是实现 URL 的重写, Nginx 的 Rewrite 规则采用 PCRE (Perl Compatible Regular Expressions) .Perl 兼容正则表达式的语法进行规则匹配,所以如果要用 Nginx 的 Rewrite 功能,必须在编译之前先安装 PCRE 库。
通过 Rewrite 可以实现规范的 URL, 根据变量来做 URL 转向及选择配置。如,MVC 框架的程序只有一个入口,可以通过 Rewrite 来实现。一些动态URL要伪装成静态HTML便于搜索引擎抓取。一些目录,域名的旧URL通过 rewrite 转到新的上面。
Nginx Rewrite 规则相关指令有:
if, rewrite, set, return, break .如:
if(!-f $request_filename){
rewrite ^/img/(.*)$ /site/$host/images/$1 last;
}
| |
| |
| |
| if($slow){ limit_rate 10k; break; } |
| |
| |
| |
| if($http_user_agent ~ MSIE){ rewrite ^(.*)$ /msie/$1 break; } if($http_cookie ~* "id=([^;] +)(?:;|$)" ){ set $id $1; } if($request_method = POST){ return 405; } if(!-f $request_filename){ break; proxy_pass http://127.0.0.1; } if($slow){ limit_rate 10k; } if($invalid_referer){ return 403; } if($args ^~ post=140){ rewrite ^ http://example.com/parm } |
| |
| |
| |
| location ~ .*\(sh|bash)?$ { return 403; } |
| |
| |
| redirect 和 permanent 用来实现 URL 跳转,浏览器地址栏显示跳转后的地址 如下面的示例.必须用 break, 用 last 会导致死循环: location /cms/{ proxy_pass http://test.somesite.com; rewrite "^/cms/(.*)\.html$" /cms/index.html break; } 如果请求的URL上有参数,如 /app/test.php?id=5 默认情况下,参数会被自动附加到rewrite 后的地址上.所以这种情况我们要在替换串后加上 ? 来解决: rewrite ^/users/(.*)$ /show?user=$1? last; 示例: rewrite ^/test(.*)$ http://www.abc.com/home permanent; 当访问 http://www.abc.com/test?id=5 时,浏览器上地址被 rewrite 成: http://www.abc.com/home?id=5 加上问号: rewrite ^/test(.*)$ http://www.abc.com/home? permanent; 地址被 rewrite 成: http://www.abc.com/home |
| location /download/ { rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break; rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break; return 403; } |
| |
| |
| |
| set $varname 'hello'; |
rewrite 可以用到的全局变量:
在 if, location, rewrite 指令中,可以使用以下全局变量;
$args
$content_length
$content_type
$document_root
$document_uri
$host
$http_user_agent
$http_cookie
$limit_rate
$request_body_file
$request_method
$remote_addr
$remote_port
$remote_user
$request_filename
$request_uri
$query_string
$scheme
$server_protocol
$server_addr
$server_name
$server_port
$uri
案例:
1.如果文件或目录不存在,重定向到 404 页面
if( !-e $request_filename){
rewrite ^/(.*)$ /index.php last;
}
2.多级目录转成参数
abc.domain.com/sort/2 => abc.domain.com/index.php?act=sort&name=abc&id=2;
if($host ~*(.*)\.domain\.com){
set $sub_name $1;
rewrite ^/sort\/(\d+)\/?$ /index.php?act=sort&name=$sub_name&id=$1 last;
}
/123456/xxxx => /xxxx?id=12345
rewrite ^/(\d+)/(.+)/ /$2?id=$1 last;
/job-123-456-789.html => /job/123/456/789.html
rewrite ^/job-([0-9]+)-([0-9]+)-([0-9]+)\.html$ /job/$1/$2/jobshow_$3.html last;
3.如果客户端使用IE浏览器,重定向到 /nginx-ie 目录下:
if($http_user_agent ~MSIE){
rewrite ^(.*)$ /nginx-ie/$1 break;
}
4.禁止访问某些目录
location ~ ^/(cron|templates)/{
deny all;
break;
}
禁止访问以 /data 开头的文件:
location ~^/data{
deny all;
}
5.只允许指定站点访问本站
if($host ~* ^(.*?)\.aaa\.com$){
set $var_tz '1';
}
if($host ~* ^192\.168\.1\.(.*?)$){
set $var_tz '1';
}
if($host ~* ^localhost){
set $var_tz '1';
}
if($
var_tz !~ '1'){
rewrite ^/(.*)$ http://www.abc.com/ redirect;
}