【问题标题】:run second Rewrite condition and rule after the first rule is executed在执行第一条规则后运行第二条重写条件和规则
【发布时间】:2022-01-03 22:58:19
【问题描述】:

我的 .htaccess 文件是:

# remove "www"
RewriteCond %{HTTP_HOST} ^www.example.com$
RewriteRule ^ https://example.com%{REQUEST_URI} [R=301,L]

# add trailing slash "/"
RewriteCond %{HTTP_HOST} ^(www\.)?example.com$
RewriteRule ^(.*(?:^|/)[^/\.]+)$ $1/ [R=301,L]

# other rules needed
RewriteCond %{HTTP_HOST} ^(www\.)?example.com$
RewriteRule ^old-link/$ https://example.com/new-link/ [R=301,L]

我的目标是让http://www.example.com/something-after 重定向到https://example.com/something-after 之后我希望在末尾添加“/”:https://example.com/something-after/

但是,我在在线测试仪中对此进行了测试,它说“测试已停止,使用不同的主机将导致重定向”在第一条规则上,因此第二条永远不会满足规则。

【问题讨论】:

  • 您是在这个帐户上托管多个域和/或子域,还是example.com 和www.example.com 是仅有的两个主机名?
  • 确实,重定向到另一台主机后重写过程终止。 BUT 对于浏览器发送到 那个 主机的请求,另一个重写过程开始 ...
  • @MrWhite,是的,这里的问题是我有多个域。如果我不这样做,也许我可以编写其他类型的规则
  • @arkascha 非常感谢。我想我理解了,也许我看到了一个不存在的问题
  • 好的,这不是问题...如果您没有多个域,则可以稍微简化规则,因为 RewriteCond 指令检查 Host 标头(在两个的规则)将是不必要的。

标签: .htaccess mod-rewrite


【解决方案1】:

我已经在在线测试器中对此进行了测试,它在第一条规则上说“测试已停止,使用不同的主机将导致重定向”,因此第二条规则从未得到满足。

大多数在线测试人员只通过指令进行一次传递(在单个请求中)。在真实服务器上,可能会发生多次传递(和多次请求)。

这些指令并没有真正的问题,只是它可能会触发多个重定向。例如。对https://www.example.com/foo 的请求将触发两个 外部重定向。第一个到https://example.com/foo(删除www),第二个到https://example.com/foo/(附加斜杠)。在极端情况下,对https://www.example.com/old-link(无尾随斜杠)的请求将触发三个外部重定向。

可以通过简单地重新排序规则并在重定向中明确包含方案+主机名以附加尾部斜杠(当前为第二条规则)来避免这些多次重定向,就像您在其他两个规则中所做的那样。此外,允许在 /old-link/ 规则上使用可选的尾部斜杠。

例如:

# Specific redirects
RewriteCond %{HTTP_HOST} ^(?:www\.)?(example\.com) [NC]
RewriteRule ^old-link/?$ https://%1/new-link/ [R=301,L]

# Add trailing slash "/"
RewriteCond %{HTTP_HOST} ^(?:www\.)?(example\.com) [NC]
RewriteRule ^(.*(?:^|/)[^/.]+)$ https://%1/$1/ [R=301,L]

# Remove "www"
RewriteCond %{HTTP_HOST} ^www\.(example\.com) [NC]
RewriteRule ^ https://%1%{REQUEST_URI} [R=301,L]

现在,只需要处理一条规则。删除 www、附加斜线和重定向 /old-link 均由单个规则处理。

其他小改动:

  • 我在 CondPattern 中捕获了域,并在 substitution 字符串中使用了 %1 反向引用。这只是省去了在 substitution 字符串中显式重复域名的麻烦。
  • 从 CondPattern 中删除了 $(字符串结束锚点)以允许以点结尾的 FQDN。
  • 在RewriteCond 指令中添加了NC 标志。 (机器人可能会请求混合大小写的 Host 标头。)
  • 无需在正则表达式字符类中对文字点进行反斜杠转义。点在这里没有特殊含义。

但是,这里的另一个问题是您当前没有 HTTP 到 HTTPS 重定向。您可以将此添加为 last 规则:

# Redirect HTTP to HTTPS
RewriteCond %{HTTP_HOST} ^example\.com [NC]
RewriteCond %{HTTPS} !on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

这只是一个标准的 HTTP 到 HTTPS 重定向,假设 SSL 证书直接安装在应用服务器上。

通过放置规则last,您只需要检查example.com(而不是www.example.com),因为请求必须已经被前面的规则规范化(以删除 www 子域) (如果需要)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 2013-04-24
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 2011-10-02
    相关资源
    最近更新 更多