Mod_Rewrite意外的行为L标志

我的web应用程序结构是:

/var/www/myapp/ - www/ - index.php - css.php - .htaccess 

虚拟主机configuration为:

 <VirtualHost *:80> ServerName www.example.org DocumentRoot /var/www/myapp/www DirectoryIndex index.php index.html <Directory /var/www/myapp/www> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny allow from all </Directory> </VirtualHost> 

在/var/www/myapp/www/.htaccess中有:

 <IfModule mod_rewrite.c> RewriteEngine on RewriteBase / RewriteRule css css.php [L,NC] RewriteRule .* index.php </IfModule> 

现在,如果我打电话给www.example.org,我被正确地redirect到index.php,但是如果我打电话给www.example.org/css,我仍然会被redirect到index.php。

如果我放下“RewriteRule。* index.php”这一行,然后调用www.example.org/css,我将被正确地redirect到css.php。

怎么了? 非常感谢

========编辑=========

 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] add path info postfix: /var/www/sviluppo/mattia_dev/example/www/DEV_2 -> /var/www/sviluppo/mattia_dev/example/www/DEV_2/css/example1/test.css 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] strip per-dir prefix: /var/www/sviluppo/mattia_dev/example/www/DEV_2/css/example1/test.css -> DEV_2/css/example1/test.css 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] applying pattern '^(DEV|TEST|PROD)\_[0-9]+\/(css|js|image|static)\/(.+)$' to uri 'DEV_2/css/example1/test.css' 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (2) [perdir /var/www/sviluppo/mattia_dev/example/www/] rewrite 'DEV_2/css/example1/test.css' -> 'css/example1/test.css' 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] add per-dir prefix: css/example1/test.css -> /var/www/sviluppo/mattia_dev/example/www/css/example1/test.css 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (2) [perdir /var/www/sviluppo/mattia_dev/example/www/] trying to replace prefix /var/www/sviluppo/mattia_dev/example/www/ with / 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (5) strip matching prefix: /var/www/sviluppo/mattia_dev/example/www/css/example1/test.css -> css/example1/test.css 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (4) add subst prefix: css/example1/test.css -> /css/example1/test.css 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b7080058/initial] (1) [perdir /var/www/sviluppo/mattia_dev/example/www/] internal redirect with /css/example1/test.css [INTERNAL REDIRECT] 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] strip per-dir prefix: /var/www/sviluppo/mattia_dev/example/www/css/example1/test.css -> css/example1/test.css 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] applying pattern '^(DEV|TEST|PROD)\_[0-9]+\/(css|js|image|static)\/(.+)$' to uri 'css/example1/test.css' 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] strip per-dir prefix: /var/www/sviluppo/mattia_dev/example/www/css/example1/test.css -> css/example1/test.css 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] applying pattern '.*' to uri 'css/example1/test.css' 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (2) [perdir /var/www/sviluppo/mattia_dev/example/www/] rewrite 'css/example1/test.css' -> 'index.php' 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] add per-dir prefix: index.php -> /var/www/sviluppo/mattia_dev/example/www/index.php 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (2) [perdir /var/www/sviluppo/mattia_dev/example/www/] trying to replace prefix /var/www/sviluppo/mattia_dev/example/www/ with / 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (5) strip matching prefix: /var/www/sviluppo/mattia_dev/example/www/index.php -> index.php 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (4) add subst prefix: index.php -> /index.php 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b63188e8/initial/redir#1] (1) [perdir /var/www/sviluppo/mattia_dev/example/www/] internal redirect with /index.php [INTERNAL REDIRECT] 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b6310db8/initial/redir#2] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] strip per-dir prefix: /var/www/sviluppo/mattia_dev/example/www/index.php -> index.php 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b6310db8/initial/redir#2] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] applying pattern '^(DEV|TEST|PROD)\_[0-9]+\/(css|js|image|static)\/(.+)$' to uri 'index.php' 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b6310db8/initial/redir#2] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] strip per-dir prefix: /var/www/sviluppo/mattia_dev/example/www/index.php -> index.php 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b6310db8/initial/redir#2] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] applying pattern '.*' to uri 'index.php' 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b6310db8/initial/redir#2] (2) [perdir /var/www/sviluppo/mattia_dev/example/www/] rewrite 'index.php' -> 'index.php' 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b6310db8/initial/redir#2] (3) [perdir /var/www/sviluppo/mattia_dev/example/www/] add per-dir prefix: index.php -> /var/www/sviluppo/mattia_dev/example/www/index.php 192.168.1.8 - - [14/Jul/2012:19:07:21 +0200] [www.example.org/sid#b747b6c0][rid#b6310db8/initial/redir#2] (1) [perdir /var/www/sviluppo/mattia_dev/example/www/] initial URL equal rewritten URL: /var/www/sviluppo/mattia_dev/example/www/index.php [IGNORING REWRITE] 

似乎发生了第一次redirect,但mod_rewrite不停止导致内部redirect。 然后,更改后的url被传递到mod_rewrite另一次,第二次redirect发生,但现在匹配第二个规则。

我无法理解,因为我已经放置了[L]标志,以确保mod_rewrite停止。

再次感谢

你错过了一个关于L标志的重要事实:

因此,如果您在这些[ .htaccess<Directory> ]上下文中使用了RewriteRule指令, 您将采取明确的步骤避免规则循环,并且不仅仅依靠[L]标志来终止一系列的规则

来自: L | last(Flag) ; 大胆的我

这意味着,只有通过使用L没有你想要的效果,以防止内部redirect。 INTERNAL REDIRECT发生在这里,因为它必须发生,你已经用你的.htaccessconfiguration指定它。 L标志不是阻止INTERNAL REDIRECT的正确标志。

让我们仔细看看你的问题和实际情况:

我无法理解,因为我已经放置了[L]标志,以确保mod_rewrite停止。

只是你有错误的L标志的未知数。 它只会停止当前重写,这意味着下面的RewriteRule指令不会在当前循环(内部循环)中处理。

如果更改的URI将重新注入下一轮(外循环),如下面的技术细节stream程图所示:

http://httpd.apache.org/docs/current/rewrite/tech.html

为了突出显示L标志在哪里以及INTERNAL REDIRECT发生的位置,这是与你的specfic(第一个)URI重写注释相同的graphics:

在这里输入图像描述

它表明, L标志只能退出内部循环,但是如果URI已被重写(更改) – 就像你的情况一样 – 外部循环会保证更改后的URI将被重新传递给所有的重写规则。

相反,您可能需要从手动显示的这一部分中为以下示例制定一个条件:

 RewriteBase / RewriteCond %{REQUEST_URI} !=/index.php RewriteRule ^(.*) /index.php?req=$1 [L,PT] 

PT有它自己的手动input ,或多或less不是解决scheme的一部分,只是注意,因为我引用了这个例子)

你实际上想要使用的是END标志:

 RewriteRule css css.php [END,NC] 

但是,如果您有所需的apache版本(请参阅2.3.9和更高版本),请联系您的系统pipe理员。 如果没有,你需要使用RewriteCond

哈克雷的答案很好地说明了正在发生的事情。 除了使用END标志之外,还有几个选项:

  • 使用%{ENV:REDIRECT_STATUS}来防止进一步重写。 内部redirect后,这将会改变。 有关更多信息,请参见此页实际发生的情况:

     RewriteCond %{ENV:REDIRECT_STATUS} ^$ RewriteRule css css.php [L,NC] 
  • 使用%{THE_REQUEST}匹配对服务器发出的请求。 由于这在内部redirect时不会改变,因此可以用来防止进一步的redirect

     RewriteCond %{THE_REQUEST} ^(GET|POST)\ /css\ HTTP RewriteRule ^ css.php [L,NC] 
  • 在查询string中使用一个虚拟variables。 这将允许通过在链接中定义这个variables来阻止redirect,但是我们将在这里使用它来防止多次传递:

     RewriteCond %{QUERY_STRING} !noredir=1 RewriteRule css css.php?noredir=1 [L,QSA,NC] 

请注意,对于这些示例中的每一个,您需要针对每个单独的规则使用此构造。