首页 > 解决方案 > htaccess:就像文件在另一个目录中一样,但 RewriteRules 似乎是互斥的

问题描述

对于 的几个子目录中的文件/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/$1 [L,qsappend]

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

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

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

标签: .htaccessredirecturl-redirectionhttp-redirect

解决方案


这是因为您首先重定向然后重写相同的 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/$1 [L,qsappend]

推荐阅读