我需要保留所有用户查询字符串。
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)在跳过的规则内不起作用。