存档

文章标签 ‘rewrite’

nginx配置文件中的rewrite参数中-f -d -e的使用误解

2009年3月8日 2 条评论

今天在写一个rewrite的时候总是不对,当中用到了文件不存在的判断,如下:

1
2
3
4
if (!-f $request_filename){
     rewrite ^(.*)$ http://site.com$1 permanent;
     break;
}

重温这几个参数的含义
-f和!-f用来判断是否存在文件
-d和!-d用来判断是否存在目录
-e和!-e用来判断是否存在文件或目录

安装我原来的理解是如果需要判断请求的目录是否存在就用d,比如/dira/
需要判断请求的目录是否存在就用f,比如/dira/filea
如果文件或者目录之一有不存在的话就用e

原来我以为/dira/filea 假如dira和filea都不存在的话随便用那个参数都能匹配
今天经过实际使用发现我完全搞错了,如果真正请求遇到上面这个目录和文件都不存在的话 !-f 和 !-d 是没法匹配的,只能用 !-e 。
正确的解释是
-e和!-e用来判断是否存在文件目录

分类: nginx相关 标签: ,

nginx多域名站点rewrite跳转不改变域名的方法:server_name_in_redirec用法

2009年1月15日 没有评论

nginx中如果一个server节点有多个域名,并且在不是访问主域名的情况下如果进行rewrite跳转,会自动把域名转换成主域名。比如:

1
2
3
4
5
server {
   server_name www.my.com www.site.com;
   rewrite ^/$ /src/login.php redirect;
   ......
}

这里如果访问www.site.com的话会自动跳转到www.my.com/src/login.php,而不是www.site.com/src/login.php。

解决方法:
如果nginx版本在0.6.x及以上版本的话使用

1
2
3
4
5
6
server {
   server_name www.my.com www.site.com;
   server_name_in_redirect  off;
   rewrite ^/$ /src/login.php redirect;
   ......
}

老版本的话可以使用

1
2
3
4
5
6
7
server {
   server_name www.my.com www.site.com;
   location = / {
      rewrite ^ /src/login.php redirect;
   }
   ......
}

关键点:
如果server_name_in_redirec为on,那么nginx将使用server_name中的第一个 server name来进行rewrite跳转。如果设置成off的话nginx将使用请求中Request Headers中的host来进行rewrite跳转。
server_name_in_redirec 可以在配置文件中 http , server 和 location 区域级别中使用。

分类: nginx相关 标签: ,

nginx配置文件中的rewrite参数

2009年1月15日 没有评论

正则表达式匹配,其中:
* ~ 为区分大小写匹配
* ~* 为不区分大小写匹配
* !~和!~*分别为区分大小写不匹配及不区分大小写不匹配

文件及目录匹配,其中:
* -f和!-f用来判断是否存在文件
* -d和!-d用来判断是否存在目录
* -e和!-e用来判断是否存在文件或目录
* -x和!-x用来判断文件是否可执行

flag标记有:
* last 相当于Apache里的[L]标记,表示完成rewrite
* break 终止匹配, 不再匹配后面的规则
* redirect 返回302临时重定向
* permanent 返回301永久重定向

一些可用的全局变量有,可以用做条件判断(待补全)
$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

分类: nginx相关 标签: ,

从apache迁移到nginx遇到的alias和rewrite问题

2009年1月14日 1 条评论

这几天在把我们网站的主web server从apache迁移到nginx上面,没想到还是遇到了些问题。
1.原来在apache每个二级域名都是用建站点的方式,我打算在nginx里面使用rewrite规则的方式来进行跳转,比如:

1
2
3
4
location /
{
     rewrite ^(.*)life.my.com(.*)$ $1www.my.com/lan28/$2 last;
}

可事实上这样写是完全没有效果的,后来分析了下实际上在 location / 里面的rewrite是只能处理hostname之后的内容就是www.my.com/(rewrite),对于hostname是没法进行rewrite的,那如果要对hostname进行rewrite怎么办呢。目前想到是把rewrite挪到location外面去,不过尝试了下貌似还是有问题,继续研究中。。。

2.原来www下面有几个alias,比如访问/wwwroot/www/php/ alias 到/wwwroot/php/ 这样,但是在nginx里面alias的话呢htm、图片等静态文件没问题,但是php问题就来了,由于php是通过正则转发到fastcgi的比如:

1
2
3
4
5
6
7
8
9
10
11
root  /wwwroot/www;
location /php/
{
     alias /wwwroot/php/;
}
 location ~ .*\.php?$
{
     fastcgi_pass  127.0.0.1:9000;
     fastcgi_index index.php;
     include fcgi.conf;
}

这种情况下如果http访问/php/*.php文件实际上是由 location ~ .*\.php?$ 处理的,也就是说php文件根本没没有进行alias还是按照/wwwroot/www/php/的路径访问的。
这个问题如何解决呢,我想到了几个方法:
1)使用symbolic link从系统上把/wwwroot/php/映射到/wwwroot/www/php/
2)修改location ~ .*\.php?$ 的正则,将/php/目录排除,然后在写一个location ~ /php/.*\.php?$ 来处理/php/下面的php文件
3)放弃alias使用rewrite的方式来处理。
三个方法第一个属于回避型,虽然能解决问题但是不符合我的要求。第二个么太复杂,能否实现还是未知。最后我选择了第三个方法就是用rewrite来处理。
略微修改了下代码

1
2
3
4
5
6
7
8
9
10
11
12
root  /wwwroot/www;
location ^~ /php/ #这里的关键就是使用“^~”,这样如果是/php/的话就不去匹配下面的php的正则,而全部重定向到php.my.com去,不然的话还是一样的htm正常,php无法访问。
{
     rewrite (.*)/php/(.*) http://php.my.com/$2 permanent;
}
location ~ .*\.php?$
{
     fastcgi_pass  127.0.0.1:9000;
     fastcgi_index index.php;
     include fcgi.conf;
}
·

这里的http://php.my.com 对应的就是/wwwroot/www/php/
这样基本就实现了需求了

分类: nginx相关 标签: , ,

apache rewrite规则中多RewriteCond条件 转换到nginx写法

2008年12月25日 没有评论

最近在迁移写应用到nginx中,在rewrite上面遇到了些问题。
虽然大部分的rewrite规则转换到nginx中几乎改动很小,但是一些特殊的比如下面这段,在nginx里面可以说完全不一样。

1
2
3
4
5
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !^.*(\.html|\.xml|\.css|\.js|\.gif|\.png|\.jpg|\.jpeg)$|.*(FCKeditor).*$|.*(fckeditor).*$|.*(userfiles).*|.*(testadow).|.*(api).*|.*(passportcode).*
RewriteRule !\.(js|ico|gif|jpg|png|css)$ /index.php
  

转换到nginx的写法(只是参照的语法,并不是上面内容的转换)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
location /xxxx/ {
         set  $test "";
 
         if ($request_method = POST) {
             set $test  P;
         }
 
         if ($http_cookie ~* "CCCC=.+(?:;|$)" ) {
             set $test  ${test}C";
         }
 
         if ($test = PC) {
           #rewrite rule goes here.
         }
}
分类: nginx相关 标签: ,