Apache .htaccess中的多个R=301重定向规则,单个重定向

Apache .htaccess中的多个R=301重定向规则,单个重定向,apache,.htaccess,mod-rewrite,Apache,.htaccess,Mod Rewrite,假设有两条重写规则我想通知浏览器: 删除www前缀(http://www.example.org至http://example.org) 删除index.php(http://example.org/index.php至http://example.org) 我希望应用这两个规则,并且我希望其中一个规则都能导致301重定向。如果两个规则都匹配,我希望只有一个301重定向 问题是,当一个规则有一个[R]标志时,我还必须指定一个[L](最后一个)标志,以根据规则的属性与之匹配 您几乎总是希望将[

假设有两条重写规则我想通知浏览器:

  • 删除www前缀(
    http://www.example.org
    http://example.org
  • 删除index.php(
    http://example.org/index.php
    http://example.org
我希望应用这两个规则,并且我希望其中一个规则都能导致301重定向。如果两个规则都匹配,我希望只有一个301重定向

问题是,当一个规则有一个
[R]
标志时,我还必须指定一个
[L]
(最后一个)标志,以根据规则的属性与之匹配

您几乎总是希望将[R]与[L]结合使用(即,使用[R,L]),因为[R]标志本身会在URI前面加上前缀,但随后会将其传递给规则集中的下一个规则,这通常会导致“请求中的URI无效”警告

是否有任何解决办法,使我可以有两个规则不导致2重定向

RewriteEngine On

# Naked domains
RewriteRule ^/?(.*)$ http://example.org/$1 [R=301,L]

# Remove index.php
RewriteRule ^index.php/(.*)$ /$1 [R=301,L]

不,L标志是告诉重写过程停止处理这些重写之后可能发生的新重写,但由于您正在执行外部重定向,我怀疑没有它会导致问题。尽管如此,真正的问题是为什么在这么简单的情况下使用mod_rewrite(或.htaccess)(mod_rewrite应该留待没有更简单的选项时使用)

这是正确的方法(无需修改)


#NameVirtualhost*:80否,L标志是告诉重写过程停止处理可能发生在这些重写之后的新重写,但由于您正在执行外部重定向,我怀疑没有它会导致问题。尽管如此,真正的问题是为什么在这么简单的情况下使用mod_rewrite(或.htaccess)(mod_rewrite应该留待没有更简单的选项时使用)

这是正确的方法(无需修改)

#名称虚拟主机*:80
#NameVirtualhost *:80 <- add and uncomment this only if your version is 2.2

<Virtualhost *:80>
    ServerName example.org
    DocumentRoot /path/to/your/htdocs
    RedirectMatch 301 ^/index.php/(.*) /$1

    #other config
</Virtualhost>

<Virtualhost *:80>
    ServerName www.example.org
    Redirect 301 / http://example.org/
</Virtualhost>
RewriteEngine on

RewriteCond %{HTTP_HOST} ^www\.(.*)
RewriteRule ^.* - [E=A:http://%1]

RewriteCond %{REQUEST_URI} ^/index.php
RewriteRule ^index.php - [E=B:/]

RewriteCond %{ENV:A} .+
RewriteCond %{ENV:B} ^$
RewriteRule ^(.*) - [E=B:/$1]

RewriteCond %{ENV:A} .+ [OR]
RewriteCond %{ENV:B} .+
RewriteRule .* %{ENV:A}%{ENV:B} [R=301,L]