【问题标题】:htaccess RewriteRule within <if> statement using HTTP_HOST使用 HTTP_HOST 的 <if> 语句中的 htaccess RewriteRule
【发布时间】:2020-09-22 20:44:14
【问题描述】:

我从一个 .htaccess 文件在一台服务器上运行多个站点,该文件具有使用一页 (index.php?pageid=x) 的自定义站点设计。根据 pageid,它会触发不同的内容/布局。

对于我在 .htccess 中使用 IF 语句的每个站点,例如:

<If "%{HTTP_HOST} == 'site.com'">     
RewriteRule goes here
</If>

如果我不在 IF 语句中,我会使用这样的重写规则:

RewriteRule ^fr/cookie-policy/$ /index.php?pageid=11 [L]

上述规则按计划工作,但如果我在 IF 语句中使用此规则,它就不起作用。我必须删除前导 ^ 并将其换成 /。但这远非理想,因为它会匹配任何带有指定模式的结尾。

谁能提出解决方案?我错过了什么?

【问题讨论】:

  • 可能与这些指令的评估顺序有关。如果您只是添加前导斜杠,即RewriteRule ^/fr/…,它是否有效?如果没有,那么在此之前可能还有更多路径段尚未被剥离。
  • @04FS 如果我按照您在 IF 语句中的建议添加前导斜杠,则会失败并显示 404。
  • 然后先弄清楚你现在处理的实际 URL 路径是什么。 RewriteRule (.*) https://example.com?path=$1 [R=302] 此时应该捕获完整路径,并进行外部重定向到 https://example.com?path=… - 该参数不会在接收端执行任何操作,但在浏览器地址栏中检查您被重定向到的位置应该清楚地显示您此时实际的 URL 路径是什么。 (是的,我的意思是https://example.com,从字面上看,不要用您自己的域替换它。)

标签: .htaccess


【解决方案1】:

&lt;If&gt; 容器改变了处理顺序。 &lt;If&gt; 容器合并很晚。见:how sections are merged in the Apache docs

这会导致&lt;If&gt; 中的RewriteRule 指令与请求映射到的绝对文件系统路径匹配,包括目录前缀,在目录中匹配时通常会删除该路径 上下文(即.htaccess)。 (也许在处理&lt;If&gt; 部分时,请求已映射回文件系统?)

RewriteRule ^fr/cookie-policy/$ /index.php?pageid=11 [L]

所以,如果fr/cookie-policy/ 是相对于文档根的,而DocumentRoot/var/www/user/public_html,那么要匹配这个完全,你需要匹配/var/www/user/public_html/fr/cookie-policy/

除非您使用附加条件(并检查 REQUEST_URI 服务器变量),否则我看不出有任何方法可以避免这种情况 - 但这似乎与这一点相悖(并且效率会降低)。

它将匹配任何以指定模式结尾的东西。

如果不指定完整的绝对文件路径,您也许可以只包含父目录(即文档根目录之上的目录)以减少发生这种情况的机会。例如。 public_html/fr/cookie-policy/$.


我注意到在 &lt;If&gt; 部分中使用 mod_rewrite 的其他一些(奇怪的)警告:

  • 您不能重写为 相对 路径(即不以斜杠或方案+主机名开头)。它需要以斜杠开头(即根相对)。重写目录上下文中的相对路径通常会导致添加回目录前缀。但是,在&lt;If&gt; 容器内,目录前缀似乎被视为*If/ - 这可能会导致“400 错误请求”。 (也许这是因为在合并&lt;If&gt; 部分时,目录前缀已经添加回来了?)

  • 与上述相关,RewriteBase 指令被“忽略”。

  • &lt;If&gt; 部分的 outside 的其他 mod_rewrite 指令(至少在相同的 context 中)似乎具有相同的行为,现在也只匹配完整的绝对文件系统路径。

  • 尽管 &lt;If&gt; 部分被“延迟”合并。它们仍然在&lt;If&gt; 部分之外的其他mod-rewrite 指令之前处理。无论指令的顺序如何。 (至少在相同的上下文中。)

  • 另见:<If> condition with HTTP_HOST in htaccess breaks PHP

通常,如果您需要在应用特定重写之前检查HTTP_HOST,那么您应该在前面的RewriteCond(条件)中检查它。但是you know that already

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多