Nginx使用重写规则重写子目录下不存在的文件

时间:2014-11-26 08:02:36

标签: .htaccess nginx rewrite

Nginx在相同位置重写.php到.php

我正在尝试将一个包含大量(.92).htaccess文件的站点从Apache移动到Nginx。 有800多个重写规则要转换。为了优化性能,我决定 将规则放在单独的嵌套位置块下(总共61个块)。

但是我在重写一些规则时遇到了问题。

的要求:

  1. / test / abc / pics /应重定向到/ test / abc / wallpapers /
  2. 如果文件存在,则应直接提供
  3. /test/abc/pics/800/a.jpg。如果它不存在, 那么请求应该重写到/test/abc/pics/pic.php,这将是 在第一次请求时创建文件。后续请求将直接提供。
  4. / test / abc应重定向到/test/abc.html
  5. /test/abc.html应该改写为/test/index.php
  6. /test/abc/def/year-2014.php应改写为/test/abc/def/index.php
  7. 所有静态文件(.gif,.jpg,.png,.mpg ....)应该以非常长的到期时间直接提供。
  8. 所有以.html结尾的文件都应该直接提供。如果该文件不存在,则应将请求重写为/fallback.php
  9. 所有以.php或/结尾的文件都应由PHP-FPM执行。如果该文件不存在,则应将其重写为/fallback.php
  10. 配置:

    index index.php;
    
    #
    # Location Specific Rules
    #
    location /test/abc/ {
        location /test/abc/pics/ {
            # For ensuring 'serve directly, if file exists' condition of Rule 2
            try_files $uri @rewrite_pics; 
        }
    
        location /test/abc/def/ {
            try_files $uri $uri/index.php @rewrite_def;
        }
    }
    
    location /test/ {
        rewrite "^/test/([a-z-]+)$" /test/$1.html permanent; # Rule 3
        rewrite "^/test/([a-z-]+).html$" /test/index.php?symbol=$1 last; # Rule 4
    }
    
    location @rewrite_pics {
        rewrite "^/test/abc/pics/$" /test/abc/wallpapers/ permanent; # Rule 1
        rewrite "^/test/abc/pics/([0-9]+)/(.*)$" /test/abc/pics/pic.php?width=$1&height=$1&pic=$2 last; # Rule 2
    }
    
    location @rewrite_def {
        rewrite "(?i)^/test/abc/def/year-([a-z]+).php$" /test/abc/def/index.php?year=$1 last;
    }
    
    #
    # Fallback Rules
    #
    location ~* \.(gif|jpg|jpeg|png|ico|3gp|flv|mpg|mpeg|mp4|mp3|swf|txt|xml|pdf|zip)$ {
        expires 1M; # Rule 5
        try_files $uri /404.php;
    }
    
    location ~ (\.php|\.html|/)$ {
        try_files $uri "${uri}index.php" /fallback.php =404;
        include php-fpm.conf;
    }
    

    php-fpm.conf

    include fastcgi.conf;
    fastcgi_index index.php;
    fastcgi_pass 127.0.0.1:9000;
    

    问题:

    1. 由于回退规则是正则表达式,因此选择它们而不是位置特定规则
    2. 如果我对所有特定于位置的规则使用~前缀,则永远不会执行回退规则。 /test/abc/pics/800/a.jpg的请求将被重写为/test/abc/pics/pic.php,这将再次与include php-fpm.conf;匹配 相同的位置配置。因此文件不会被执行并按原样下载。
    3. 因此,我将“/test/abc/pics/”添加到所有位置块(命名位置除外)。但这会导致一切 .jpg下的请求(包括现有的.php文件)传递给PHP-FPM。这导致访问被拒绝错误, 由于security.limit_extensions仅允许{{1}}分机。
    4. 我在这里做错了什么?是否有一种简单的方法可以根据扩展名提供所有现有文件 并且只有不存在的文件与位置块/重写规则匹配?

0 个答案:

没有答案