1

我的目标是从这些路径重定向用户:

/foo/index.php
/foo/

/index

/index已从/foo/index.php.

这可能.htaccess吗?

到目前为止,我已经尝试过:

RewriteRule ^foo/(index\.php)?$ /index [R=301,QSA,L]
RewriteRule ^index$ /foo/index.php [QSA,L]

但这会进入无限重定向循环。我认为RewriteCond为 URI 添加一个会有所帮助,但来自文档

注意:RewriteRule在模式匹配后正在处理条件。

所以在我的用例中显然RewriteCond不会有太大用处。

浏览Rewrite Flags 文档,该S标志似乎是我正在寻找的:

如果当前规则匹配,此标志强制重写引擎按顺序跳过下一个 num 规则。使用它来构建伪 if-then-else 结构:then-clause 的最后一条规则变为 skip=N,其中 N 是 else-clause 中的规则数。

所以我试过:

RewriteRule ^index$ /foo/index.php [QSA,L,S=1]
RewriteRule ^foo/(index\.php)?$ /index [R=301,QSA,L]

虽然,因为我有L旗帜,S旗帜似乎有点多余。尽管如此,在我看来,逻辑似乎是正确的,尽管这仍然处于无限重定向循环中。

现在我正在使用 PHP 的解决方法。首先,Apache 在内部将新 URL 重写为旧 URL,然后在 PHP 中检查是否$_SERVER['REQUEST_URI']与脚本开头的新格式匹配,否则会导致 301 重定向到新 URL。

不过,我想知道这是否可以.htaccess单独使用?或者,如果有人可以解释我如何/为什么使用上面的重写规则获得无限循环,我将不胜感激。

4

1 回答 1

1

问题是规则在一个.htaccess文件中,正如文档所说,这个文件在每次重写循环后都会重新解析,让它可能适用.htaccess于不同目录中的 a 。因此,您的L旗帜都是徒劳的。

我环顾四周,如果你真的不能将重写规则放在主 apache 配置中,我可以提供以下内容:因为服务器变量THE_REQUEST在重写运行之间没有更新,所以可以得出“浏览器可见 URL”来自在那里并防止在这种情况下重写:

# external redirect to /index (unless browser already shows /index plus query params)
RewriteCond %{THE_REQUEST} !^\w+\ /index(\?.*)?\ HTTP/1..$
RewriteRule ^foo/(index\.php)?$ /index [R=301,QSA,L]

# internal redirect for /index
RewriteRule ^index$ /foo/index.php [QSA,L]

我认为还有另一个变量保持不变,但现在我找不到它。也许是其他人?

于 2013-02-12T22:57:46.440 回答