自定义.htaccess重写规则的意外行为

时间:2015-10-19 16:50:22

标签: regex apache .htaccess mod-rewrite redirect

所以我一直在研究一些没有按预期工作的重写规则。这些是我试图重写的一些示例请求:

/             -> /index.php?page=Home
/Home         -> /index.php?page=Home
/Teaching/Foo -> /index.php?page=Teaching&id=Foo
/Teaching/Bar -> /index.php?page=Teaching&id=Bar
/Download/ue8 -> /index.php?action=Download&id=ue8
/Download/24a -> /index.php?action=Download&id=24a
(default)     -> /index.php?page=Home
** OR ALTERNATIVELY **
(default)     -> /index.php?page=FileNotFound
(and maybe rewrite the visible URL to /FileNotFound)

我主要希望隐藏尽可能多的网址并阻止目录列表和直接访问位于特定文件夹中的文件,并且只允许通过/Download/FileId访问可下载文件,同时让我的常用页面不同讲座可通过/Teaching/SomeLecture访问。

到目前为止,我一直在使用此代码段来处理/Home/Teaching内容:

RewriteEngine On
RewriteBase /

# Redirect Trailing Slashes
RewriteRule ^(.*)/$ /$1 [L,R=301]

# Handle Front Controller
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^Teaching/([A-Za-z0-9]*)$ index.php?page=Teaching&id=$1 [L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^Home$ index.php?page=Home [L]

RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s(.*)/index\.php [NC]
RewriteRule ^ %1 [R=301,L]

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [L,R=301]

我不完全确定所有这些指令,我注意到,目前存在一些缺陷。

  1. 尝试访问不存在的文件,例如/Files/Bad/Path.pdf,将用户转发到/?page=Home,应将其重定向到//Home或显示/index.php?page=FileNotFound的内容,而不更改网址或重定向到/FileNotFound,取决于(default)的规则。我不确定哪种解决方案在这种情况下最适合。
  2. 尝试访问某些确实存在的文件夹会导致无限重定向循环,而不存在的文件夹显然会重定向到/。在这两种情况下,我认为重定向到/FileNotFound我认为是正确的吗?
  3. 在这种情况下,你能否制定一套可能符合我需要的规则?

1 个答案:

答案 0 :(得分:1)

.htaccess中有许多冗余指令。用这个替换你所有的.htaccess:

# Turn off mod_spelling
<IfModule mod_speling.c>
   CheckSpelling off
   CheckCaseOnly off
</IfModule>

Options -MultiViews
RewriteEngine On
RewriteBase /

# block direct access to file and directories in these directories
RewriteCond %{REQUEST_URI} !\.(?:jpe?g|gif|bmp|png|tiff|css|js)$ [NC]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(Templates|Files) - [NC,F]

# remove index.php
RewriteCond %{THE_REQUEST} /index\.php [NC]
RewriteRule ^(.*?)index\.php$ /$1 [L,R=301,NC,NE]

# Redirect Trailing Slashes
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]

# Handle Front Controller
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(Download|Teaching)/([\w-]+)/?$ index.php?page=$1&id=$2 [L,QSA,NC]

RewriteRule ^(Home)?/?$ index.php?page=Home [L,NC,QSA]

确保在测试之前清除浏览器缓存。