【问题标题】:RewriteRule being greedyRewriteRule 是贪婪的
【发布时间】:2011-02-10 02:25:35
【问题描述】:

我已经找了几个小时的答案了,很抱歉,如果这个问题被问了很多次,我错过了。

我基本上想重写以忽略第一个目录。路径中的第一个目录会有所不同,所以我认为我可以使用正则表达式。但是我的正则表达式一直与文件名匹配:

RewriteRule ^([a-z]+)?/(.+)$ $2 [L]

如果我深一层,这可行:

http://test.domain.com/one/index.php

我得到了根目录的实际索引页。这就是我想要的。但如果我要更深入:

http://test.domain.com/one/two/anotherfile.php

我收到一条消息说 /anotherfile.php 未找到,因为它正在根目录中查找它。所以看起来我的正则表达式在最后一个 [a-z] 之后没有停止。感谢您的帮助。

如果这很重要的话,这就是 Apache2。

【问题讨论】:

  • 假设输入是 one/index.phpone/two/anotherfile.php,正则表达式按预期工作 - 它确实为第二个字符串返回 two/anotherfile.php。您的问题可能出在其他地方吗?你能发布更多细节吗?
  • 谢谢,但我不知道还能是什么。这是我所拥有的: RewriteEngine On RewriteCond %{REQUEST_URI} !^/lib RewriteCond %{REQUEST_URI} !^/images RewriteRule ^([az]+)?/(.+)$ $2 [L] this: test.domain.com/one/two/index.php返回完全相同的页面(/index.php):test.domain.com/one/index.php
  • 还有什么我应该尝试的吗?它必须是正则表达式是贪婪的。如果我将正则表达式更改为 "RewriteRule ^(one)?/(.+)$ $2 [L]" 它工作正常。但我希望使第一个目录动态化。
  • 正则表达式不应该那样做,但可以试试RewriteRule ^([a-z]+)/(.+)$ $2 [L]。第一组不是可选的 - 我不知道 Apache RewriteRule,但我假设如果它失败了它会继续前进,所以这应该没问题。
  • 我已经在两台服务器上尝试过这个,我得到了相同的行为。有谁能够验证这应该有效吗?如果是这样,我知道问题出在其他地方。

标签: regex apache mod-rewrite


【解决方案1】:

重写引擎重复所有规则,直到在规则迭代之前和之后的 URI 相同。给定规则RewriteRule ^([a-z]+)?/(.+)$ $2 [L] 和输入:http://test.domain.com/one/index.php,这就是正在发生的事情:

  1. 从 URI 中删除前导斜杠(前缀):one/index.php
  2. 应用规则,URI 匹配^([a-z]+)?/(.+)$
  3. URI 被重写为/index.php
  4. 内部重定向,新 URI (/index.php) 与旧 URI (/one/index.php) 不匹配,并通过重写规则返回
  5. 删除了前导斜线
  6. 应用了规则,URI 匹配^([a-z]+)?/(.+)$
  7. URI 未被重写。新 URI (/index.php) 在通过重写引擎 (/index.php) 运行之前与旧 URI 相同,重写停止

生成的 URI 是 /index.php

但是输入:http://test.domain.com/one/two/anotherfile.php

  1. 从 URI 中删除前导斜杠(前缀):one/two/anotherfile.php
  2. 应用规则,URI 匹配^([a-z]+)?/(.+)$
  3. URI 被重写为/two/anotherfile.php
  4. 内部重定向,新 URI (/two/anotherfile.php) 与旧 URI (/one/two/anotherfile.php) 不匹配,并通过重写规则返回
  5. 删除了前导斜杠 (two/anotherfile.php)
  6. 规则已应用,URI 匹配^([a-z]+)?/(.+)$
  7. URI 被重写为/anotherfile.php
  8. 内部重定向,新 URI (/anotherfile.php) 与旧 URI (/two/anotherfile.php) 不匹配,并通过重写规则返回
  9. 删除了前导斜杠 (anotherfile.php)
  10. 应用了规则,URI 匹配^([a-z]+)?/(.+)$
  11. URI 未被重写。新 URI (/anotherfile.php) 在通过重写引擎 (/anotherfile.php) 运行之前与旧 URI 相同,重写停止

生成的 URI 是 /anotherfile.php

[L] 不会阻止生成的 URI 通过重写引擎放回,它只是停止当前迭代的重写过程。您需要更改正则表达式或添加某种重写条件。一种可能性是在您拥有的之前添加RewriteRule ^[a-z+]/([a-z]+)?/(.+)$ $2 [L],以便分别处理 2 个深层目录。

【讨论】:

    【解决方案2】:

    嗯嗯……

    抛出一些想法:

    1. 我认为可能存在递归RewriteRule-ing...但我不确定,因为您将“最后”规则放在那里。 但是,这是我认为可以解释正在发生的事情的唯一合乎逻辑的事情。

      1. 这与您的 Regex 不停止不同 - 这将是 Apache 在我们告诉它放弃很久之后仍在继续。
    2. 如果 Apache 没有停止,我不确定您有什么追索权。可能是RewriteCondDPI(DPI 丢弃PATH_INFO)、分析THE_REQUEST,还是更多?

    很抱歉,我无法提供更多帮助。我希望你在过去的一年里解决了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-10
      • 1970-01-01
      • 2011-08-25
      • 2014-08-21
      相关资源
      最近更新 更多