1

有以下规则:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.+) dir/index.php?$1 [L]
RewriteRule dir/index\.php.* - [F]

为什么最后一条规则被处理并为所有请求返回 Forbidden ?

我需要如果找不到文件或目录,则不应处理下一条规则。

下一个示例也不适用于我:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .? - [S=1]
RewriteRule dir/index\.php.* - [F]
RewriteRule (.+) dir/index.php?$1

它仍然为所有请求返回 Forbidden。

4

2 回答 2

2

为什么最后一条规则被处理并为所有请求返回 Forbidden ?

foobar请求 URL 时:

  • 两个条件(第 2、3 行)匹配
  • 模式匹配,生成的 URL 变为dir/index.php?foobar(第 4 行)
  • [L]标志会导致重写停止——它不会阻止 Apache 再次访问重写的 URL,因为它已经改变(见下文)。

作为dir/index.php输入 URL:

  • 由于文件存在,条件不匹配(第 2 行)
  • 跳转到第 5 行
  • 模式匹配,因此出现 Forbidden 错误

当目录或文件名更改时,Apache 必须重新评估各种配置部分(例如DirectoryFiles)以及.htaccess“重写”路径的文件。这就是为什么 Apache 可能会执行另一次迭代,即使前一个迭代被[L]标志结束。

最后一个字符串应该限制对 UFL 处理程序的直接访问。直接访问意味着通过以下链接请求文件:domain.com/dir/index.php

我认为在第 5 行之前添加另一个条件应该可行:

RewriteCond %{THE_REQUEST} dir/index\.php\x20HTTP/\d\.\d$
RewriteRule . - [F]

server 变量包含浏览器发送的THE_REQUEST请求,没有应用任何重写。这对于检测浏览器最初请求的页面可能很有用。

THE_REQUEST

浏览器向服务器发送的完整 HTTP 请求行(例如,“GET /index.html HTTP/1.1”)。这不包括浏览器发送的任何附加标头。与下面的大多数其他变量不同,该值尚未被转义(解码)。

于 2012-12-26T10:59:58.117 回答
0

我不确定您所说的“下一条规则”是什么意思。

但是,如果您不希望在请求不存在的文件时执行某些规则,那么使用以下结构可能会有所帮助。(以下代码是从Apache RewriteRule Flags Page复制的)

# Is the request for a non-existent file?
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# If so, skip these two RewriteRules
RewriteRule .? - [S=2]

    RewriteRule (.*\.gif) images.php?$1
    RewriteRule (.*\.html) docs.php?$1

并且还使用 [R] 而不是 [L] 进行重定向可能有助于解决为所有请求返回 Forbidden 的问题。

于 2012-12-26T10:40:43.767 回答