【问题标题】:Order of rules in .htaccess file.htaccess 文件中的规则顺序
【发布时间】:2013-05-24 01:06:57
【问题描述】:

我有一个这样的 .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]应该防止任何其他规则发生。

【问题讨论】:

    标签: apache .htaccess mod-rewrite


    【解决方案1】:

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

    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]
    

    【讨论】:

    • 如果应用第二条规则,那么 [L] 标志的意义何在?
    • [L] 标志不会停止进程。检查technical details
    • 学到了一些新东西。对于他们如何处理规则和条件,这绝对是违反直觉的。 +1
    • @AbsoluteƵERØ 事实上。这适用于每条规则,但通常无论如何都会处理所有规则。
    • 您在该页面上看到的与此相矛盾的内容来自标志文档:“[L] 标志导致 mod_rewrite 停止处理规则集。在大多数情况下,这意味着如果规则匹配,将不再处理任何规则。"?
    【解决方案2】:

    ^ 表示字符串的开头。

    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
    

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

    【讨论】:

    • 谢谢您,但在这种特殊情况下,我可以向您保证不区分大小写,并且毫无疑问路径以“foo”开头。事实证明,当删除两条规则中的第二条时,它会按预期工作。
    【解决方案3】:

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

    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]
    

    【讨论】:

    • “RewriteCond 行仅适用于第一条规则”——我不明白。即使它们被应用于第一条规则,那么第一条规则也正确匹配并具有 [L] 标志,因此第二条规则永远不应触发。
    • 第二条规则在第一条规则完成后触发。只要满足条件,Apache 就会继续应用所有规则。
    猜你喜欢
    • 2010-11-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    • 1970-01-01
    相关资源
    最近更新 更多