.htaccess重写多级子目录异常

时间:2012-01-11 18:27:33

标签: .htaccess

我一直在使用我自己的自定义CMS在我的服务器上使用.htaccess脚本来清理URL:

# this is the initialization
Options         +FollowSymLinks
RewriteEngine   On
RewriteBase     /
# these are the rewrite conditions
RewriteCond     %{REQUEST_FILENAME}     !-f
RewriteCond     %{REQUEST_FILENAME}     !-d
# and finally, the rewrite rules
RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1 [L,QSA]
RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$   /pages.php?which_page=$1&data1=$2 [L,QSA]
RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3 [L,QSA]
RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4 [L,QSA]
RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4&data4=$5 [L,QSA]
RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4&data4=$5&data5=$6 [L,QSA]
RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4&data4=$5&data5=$6&data6=$7 [L,QSA]

这非常适合将所有请求重定向到我的CMS的pages.php脚本。

问题是,在极少数情况下我有一个客户端想要添加一个子目录,在该子目录中他们可以添加无限的额外子目录,所有这些子目录都需要重定向到其中的index.html。对于此讨论,我们可以调用此主要子目录main-dir,当用户访问www.mysite.com/main-dir时,应将其重定向到www.mysite.com/main-dir/index.html

如果客户端在main-dir中添加了更多目录,则方向应该是其中的index.html。 www.mysite.com/main-dir/some-dir/index.html

所以基本上我需要从常规pages.php重定向中豁免main-dir及其任何子目录,并确保它们都重定向到其中的index.html。

我已经尝试了很多东西来完成这项工作,包括在子目录中添加一个.htaccess文件,只有“RewriteEngine off”并添加各种条件和规则,例如:

RewriteCond%{REQUEST_URI}!^ / collections / ^

RewriteRule ^(集合)/ $ 1 [L]

没有任何效果。

目前,如果网络用户访问www.mysite.com/main-dir,他们会被重定向到pages.php脚本,但如果他们访问www.mysite.com/main-dir/index则不会获得豁免。他们确实进入了html页面。

任何帮助都将不胜感激。

好吧,

Ydragon

2 个答案:

答案 0 :(得分:2)

你必须在每个RewriteRule中使用负向前瞻,如下所示:

RewriteRule     ^(?!main-dir/)([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1 [L,QSA]
RewriteRule     ^(?!main-dir/)([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$   /pages.php?which_page=$1&data1=$2 [L,QSA]
RewriteRule     ^(?!main-dir/)([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3 [L,QSA]
RewriteRule     ^(?!main-dir/)([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4 [L,QSA]
RewriteRule     ^(?!main-dir/)([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4&data4=$5 [L,QSA]
RewriteRule     ^(?!main-dir/)([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4&data4=$5&data5=$6 [L,QSA]
RewriteRule     ^(?!main-dir/)([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4&data4=$5&data5=$6&data6=$7 [L,QSA]

这将使上述规则适用于 /main-dir/之外的所有内容。

同样在index.html内部/main-dir/服务,您不需要做任何事情,因为默认情况下会在Apache中显示。

答案 1 :(得分:0)

只需将以下内容添加到htaccess的顶部即可。这将阻止url被重写为pages.php是url的第一部分是根目录中的现有目录。因此,如果存在名称为xxx的目录,则不会重写example.com/xxx/whatever/。

RewriteCond %{DOCUMENT_ROOT}/$1 -d
RewriteRule ^([^/]+)(/(.*))?$ - [L]

你的RewriteCond看起来没问题,但是你必须在每个RewriteRule面前重复它。其他两个(... !-d... !-f)也是如此。但我建议我在下面使用的方式,所以你不必一遍又一遍地重复它们。

最后你的htaccess应该是这样的:

# this is the initialization
Options         +FollowSymLinks
RewriteEngine   On
RewriteBase     /
# don't rewrite if any of these conditions 
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* - [L]

RewriteCond %{DOCUMENT_ROOT}/$1 -d
RewriteRule ^([^/]+)(/(.*))?$ - [L]


# Rewrite all other matching urls to pages.php

#leave old rewrite rules (without the conditions) here, or use the much sorter version I would suggest.
RewriteRule     ^([^/]+)(?:/([^/]+))?(?:/([^/]+))?(?:/([^/]+))?(?:/([^/]+))?(?:/([^/]+))?(?:/([^/]+))?/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4&data4=$5&data5=$6&data6=$7 [L,QSA]

#old rules
#RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1 [L,QSA]
#RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$   /pages.php?which_page=$1&data1=$2 [L,QSA]
#RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3 [L,QSA]
#RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4 [L,QSA]
#RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4&data4=$5 [L,QSA]
#RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4&data4=$5&data5=$6 [L,QSA]
#RewriteRule     ^([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/([a-zA-Z0-9\-\_\ \+\-]+)/?$    /pages.php?which_page=$1&data1=$2&data2=$3&data3=$4&data4=$5&data5=$6&data6=$7 [L,QSA]