当前位置: > Linux服务器 > nginx >

Nginx 重写URI

时间:2015-01-17 14:49来源:blog.itpub.net 作者:IT

重写URI

 
    我们在使用Nginx的过程中经常碰到需要将客户端访问者的URI进行重写,在“根据浏览器选择主页”部分多少有些认识这种做法,另外我们我们在“map模块的使用”部分也见到和改写过,但是它们都没有rewrite模块强大,因此,在这一部分我们看看rewrite的用法。
 
    使用rewrite模块离不开正则表达式,因此,要想使用rewrite指令,那么就必须在安装Nginx时指定pcre。
 
使用该模块通过正则表达式(PCRE)就可以改变URI,并且可以重定向和根据变量来选择配置。如果在server级别执行rewrite指令,那么请求将在location确定之前执行。如果在被选择的location中仍有rewrite指令,那么它们同样被执行,如果在这个location中又触发访问到rewrite指令,那么就会再次改变URI。这种被重复周期为10才, 在10次之后仍然找不到具体的URI,那么Nginx将会返回500错误。
 

配置示例

 
rewrite ^/(/d+)/(.+)/ /$2?id=$1 last;
 
rewrite ^/([0-9a-z]+)job/(.*)$ /area/$1/$2 last;
 
if (-d $request_filename){ 
rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent; 
}
 
if ($http_host ~* "^(.*)/.st/.xx/.com$") { 
rewrite ^(.*) http://st.yy.com$1; 
break; 
}
 
if ($host ~* (.*)\.xx\.com) {
           set $sub_name $1;  
           rewrite ^/sort\/(\d+)\/?$ /index.php?act=sort&cid=$sub_name&id=$1 last;
       }
 
if ($http_user_agent ~ MSIE) {
           rewrite ^(.*)$ /var/www/ie/$1 break;
}
    
 

安装PCRE

 
    下载并安装pcre:
 
[root@s29 ~]# wget ftp://ftp.csx.cam.ac.uk/pub/software \
> /programming/pcre/pcre-8.13.tar.gz
[root@s29 ~]#tar -zxvf pcre-8.13.tar.gz 
[root@s29 ~]#cd pcre-8.13
[root@s29 pcre-8.13]#./configure --prefix=/usr/local/pcre-8.13   \
> --enable-utf8 --enable-unicode-properties
[root@s29 pcre-8.13]#make
[root@s29 pcre-8.13]#make install
    
    需要注意的是,在安装Nginx时:
 
[root@mail nginx-1.0.2]# ./configure --prefix=/usr/local/nginx-1.0.2-pcre-8.13 \
> --with-pcre=/root/pcre-8.13
 
   ……
 
Configuration summary
  + using PCRE library: /root/pcre-8.13
  + OpenSSL library is not used
  + md5: using system crypto library
  + sha1 library is not used
  + using system zlib library
 
   ……
 
    
    这里的--with-pcre指定的是pcre-8.13的源码,但是在Nginx的安装过程中会查找pcre安装的具体情况:
 
.....//无法上传省略
 
 
指令名称:if 
语    法: if (condition) { ... } 
默 认 值: none 
使用环境: server, location 
功    能:用于检测条件是否成立,如果条件被评估为真,那么在大括号“{}”中代码将会被执行,同配置中一致的请求将会被处理。if指令内部的配置会被从上一级继承。需要注意的是,使用if指令要谨慎,尽量考虑是try_files指定。
 
条件condition部分可以指定下列值:
 
n  使用= 或 !=操作符比较变量的表达式;
n  变量名称,如果变量名称为false,那么值将会是一个空字符串(""),或者是
任何以"0"开始的字符串
n  使用正则表达式的模式匹配:
u             ~    执行区分大小写匹配;
u             ~*   执行不区分大小写匹配;
u             !~   执行区分大小写不匹配
u             !~*  执行不区分大小写不匹配
n  使用 -f 或者 !-f 操作符检测文件的存在性;
n  使用 -d 或者 !-d 操作符检测目录的存在性;
n  使用 -e 或者 !-e 操作符检测文件、目录或者符号连接的存在性;
n  使用 -x 或者 !-x 检测文件是否可执行。
 
正则表达式部分可以放在括号内,以便在以后的使用中可以通过变量$1 到 $9来访问。例如:
 
if ($http_user_agent ~ MSIE) {
  rewrite  ^(.*)$  /msie/$1  break;
}
 
if ($http_cookie ~* "id=([^;] +)(?:;|$)" ) {
  set  $id  $1;
}
 
if ($request_method = POST ) {
  return 405;
}
 
if ($slow) {
  limit_rate  10k;
}
 
if ($invalid_referer) {
  return   403;
}
 
if ($args ~ post=140){
  rewrite ^ http://example.com/ permanent;
}
 
 
        在条件判断中可以使用的一些全局变量:$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。
 
指令名称:return
功    能: 该指令会结束执行规则,并且会为客户端返回状态码。可使用的代码值:204, 400, 402-406, 408, 410, 411, 413, 416 和 500-504,此外,非标准的代码444将会关闭连接而不会发送任何头
功    能: return code 
默 认 值: none 
使用环境: server, location, if 
 
指令名称:rewrite 
语    法: rewrite regex replacement flag 
默 认 值: none 
使用环境: server, location, if 
功    能:该指令会按照相关的regex正则表达式和replacement替换字符串改变URI,rewrite指令会按照自己在配置文件中出现的顺序执行,这一点要格外注意。
如果replacement替代字符串由http://开始,那么客户端将会被重定向redirect,任何其它后面的rewrite指令都被终结。
 
标志flag用于结束rewrite指令,它的可取值有:
 
l         last - 在搜索到相应的URI和location之后完成rewrite指令;
l         break - 完成 rewrite指令处理
l         redirect - 返回302临时重定向,如果replacement替换部分是由http://开始,它将被应用。
l         permanent - 返回30代码永久重定向 
 
注意,如果重定向是相当的,即没有主机部分,那么当使用重定向时,Nginx使用"Host"头的顺序为:如果有匹配server_name指令指定的主机名,那么则使用它;如果没有,那么将会使用第一个server_name设置的值;如果仍然没有,那么本地主机名会被使用。如果想让Nginx总是使用"Host"头,那么可以在server_name指令中使用"*"(但是这么做会有限制)。例如:
 
rewrite ^(/download/.*)/media/(.*)\..*$  $1/mp3/$2.mp3  last;
rewrite ^(/download/.*)/audio/(.*)\..*$  $1/mp3/$2.ra   last;
return  403;
    
    如果我们将这些指令放置在/download/中,那么有必要将标志"last" 替换为 "break",否则Nginx在经过10 循环后将会返回500错误:
 
location /download/ {
  rewrite ^(/download/.*)/media/(.*)\..*$  $1/mp3/$2.mp3  break;
  rewrite ^(/download/.*)/audio/(.*)\..*$  $1/mp3/$2.ra   break;
  return  403;
}
 
    
    如果在replacement替换部分包含参数,那么其余的参数添加在后面,另外,为了避免参数部分再被附加,可以在参数部分最后一个字符后再放置一个”?”。例如:
 
rewrite  ^/users/(.*)$  /show?user=$1?  last;
   
    注意使用大括号( { 和 } ),由于它们可以同时使用在正则表达式和区段(就是http、server、location、if)控制中,为了避免歧义、冲突,因此在正则表达式中使用大括号( { 和 } )那么将它们使用双引号或者单引号来括起。例如:
 
    我们将/photos/123456  重定向该URL到
 
/path/to/photos/12/1234/123456.png


(责任编辑:IT)
------分隔线----------------------------
栏目列表
推荐内容