0

我有一个这样的 .htaccess 文件:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^foo.*$ /cgi/foo.cgi [L]
RewriteRule ^.*$ /cgi/fallback.cgi [L]

但是当我转到该文件夹​​中以 foo 开头的 URL 时,浏览器仍然会被重定向到fallback.cgi脚本。如果我删除第二条规则,“foo”行就可以了。

根据我的理解,第一条规则应该优先,[L]应该防止任何其他规则发生。

4

3 回答 3

3

你是对的,应该首先应用第一条规则,我认为是。问题可能是第二条规则也被应用了,所以代码应该是这样的:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^foo.*$ /cgi/foo.cgi [L,NC]

RewriteCond %{REQUEST_URI} !/cgi/(foo|fallback)\.cgi [NC]
RewriteCond %{REQUEST_URI} !/foo [NC]
RewriteRule ^.*$ /cgi/fallback.cgi  [L]
于 2013-05-22T23:20:11.257 回答
1

表示字符串的^开头。

RewriteRule ^foo.*$ /cgi/foo.cgi [L]

因此,该规则仅匹配 /foo 后跟零个或多个字符。

要匹配以“foo”开头的文件,请使用:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (^|/)foo.*$ /cgi/foo.cgi [L]

它匹配:

/foo
/foo.php
/food.php
/foolish/dog

它不匹配:

/kung-foo.cat
/FOO.php

更新 请记住,某些浏览器会重定向缓存。我在自己的服务器上对此进行了测试,并执行了缓存的重定向。当我的新规则不起作用时,让我有点困惑。

于 2013-05-22T22:05:23.333 回答
1

它正在应用第二条规则,因为;

  1. 在第二条规则中,您匹配.*(意味着一切)
  2. RewriteCond行仅适用于第一条规则

正确的代码是:

Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /

# don't do anything for a file, dir or symlnk
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-d [OR]
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^ - [L]

RewriteRule (^|/)foo /cgi/foo.cgi [L,NC]

RewriteRule ^ /cgi/fallback.cgi [L]
于 2013-05-22T22:49:41.237 回答