一个 RewriteCond 对应多个 RewriteRule

一个 RewriteCond 对应多个 RewriteRule

我需要保留所有用户查询字符串。

RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^$ index.html?page=home&%1

RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^about$ index.html?page=about&%1

RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^contact$ index.html?page=contact&%1

如何为所有 RewriteRules 指定 RewriteCond ?

由于这是一个小型静态网站,我并不期待单一的通用控制器 RewriteRule。

答案1

对于您的三个示例,这些将​​起作用:

RewriteRule ^$ index.html?page=home [QSA,L]
RewriteRule ^about$ index.html?page=about [QSA,L]
RewriteRule ^contact$ index.html?page=contact [QSA,L]

诀窍在于“QSA”标志。

编辑:一个稍微更通用的解决方案,它基于 Drupal 的做法:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.html?page=$1 [L,QSA]

!-f 很重要,因为否则您无法提供图像或 index.html 本身。您可以删除 !-d 行,具体取决于您要做什么。稍微不同的方法可能是:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)$ index.html?page=$1 [L,QSA]

这将捕获 /foo 和 /bar,但不会捕获 /foo/、/bar/ 或 /foo/bar。

答案2

除了可以使用 QSA 之外,您是否知道您可以%{QUERY_STRING}在 RewriteRule 中使用权利?:

RewriteRule ^$ index.html?page=home&%{QUERY_STRING}
RewriteRule ^about$ index.html?page=about&%{QUERY_STRING}
RewriteRule ^contact$ index.html?page=contact&%{QUERY_STRING}

与 QSA 标志相比,此方法的优点在于您可以控制生成的查询字符串中的参数顺序。例如:

    RewriteRule ^contact$ index.html?%{QUERY_STRING}&page=contact

这样可以确保“page”参数始终设置为“contact”,即使它已包含在原始查询字符串中。(至少对于 PHP 来说这是正确的,因为 PHP 的查询字符串解析器始终将多个相同参数中的最后一个返回到 $_GET 数组中。)

一个 RewriteCond 对应多个 RewriteRule

您的标题暗示了另一个也可以解决的问题:

您可以使用 RewriteRule 标志S|skip将多个 RewriteRules 绑定到单个 RewriteCond(或一组 RewriteCond)。以下是将一个 Cond 应用于三个规则的示例:

RewriteCond  %{HTTP_HOST}  !^www.mydomain.com$  [NC]
# skip rules if NOT within domain - only way to tie multiple rules to one cond
RewriteRule  .?  -  [S=3]
RewriteRule  ^path1(/.*)$  /otherpath1$1
RewriteRule  ^path2(/.*)$  /otherpath2$1
RewriteRule  ^path3(/.*)$  /otherpath3$1

但这并不能解决您的原始问题,因为对 RewriteCond 的反向引用(例如您例子中的 %1)在跳过的规则内不起作用。

相关内容