htaccess:就像文件在另一个目录中一样,但 RewriteRules 似乎是相互排斥的

htaccess: act as if files were in another directory, but RewriteRules seem to be mutually exclusive

对于/data/的几个子目录中的文件,我想将它们(以及其中的文件)视为在根目录中。

所以,

1) 请求

/data/foobar/file.png

应该将浏览器重定向到

/foobar/file.png

2) 对

的任何请求
/foobar/file.png

应该分别传送文件/data/foobar/file.png,但没有重定向。


对于 1) 我使用了以下规则 :

RewriteCond %{REQUEST_URI} ^(.*)?data/((foobar|and|some|other|subdirs)/.*)$
RewriteRule .* %1%2 [R=301,L,qsappend]

(我采用这种方法使用 RewriteCond%x 引用,以便与子目录无关,因为在我的开发环境中,页面位于子目录中与位于域根目录的实时系统相反。)

对于 2),以下规则可以解决问题:

RewriteRule ^((foobar|and|some|other|subdirs)/.*)$ data/ [L,qsappend]

但是,这些规则只有在我一次启用一个时才有效。如果我同时启用它们,浏览器将中止请求并显示 "too many redirects" 错误。从 /data/*/* 的重定向将起作用,但随后以中止的请求结束,就像在没有 /data/*.

的情况下调用 URL 一样

我很难理解为什么会这样。如果这两个规则都触发了重定向,那将是完全合乎逻辑的。但就我对 htacccess 的理解(开发控制台的“网络”选项卡似乎证实了这一概念)而言,客户端甚至不应该知道情况 2)该文件实际上并不存在。那么为什么这显然仍然计入重定向限制?

我缺少什么基本的东西吗?我怎样才能实现我想要实现的目标?

这是因为您先重定向然后重写相同的 Uri 。您的第二条规则与第一条规则冲突。 您需要匹配 %{THE_REQUEST} 而不是 %{REQUEST_URI} 以避免重定向循环

RewriteCond %{THE_REQUEST} \s(.*)?data/((foobar|and|some|other|subdirs)/.*)\s
RewriteRule .* %1%2 [R=301,L,qsappend]
RewriteRule ^((foobar|and|some|other|subdirs)/.*)$ data/ [L,qsappend]