所以我很难弄清楚为什么我的重写规则不会触发。这些规则位于我网站的子域根目录中的.htaccess
文件中。我已经在 VirtualHost 中为mod_rewrite打开了详细的日志记录,但这并不能真正帮助我解决问题所在,尽管前三条规则似乎只是巧合,因为它们的文件存在于请求的位置。
这组规则的目标是:sub.domain.tld/
-> 直通/提供实际文件sub.domain.tld/?q=test
-> 直通/提供具有查询参数不变
的实际文件sub.domain.tld/.well-known/*
->直通/服务实际文件(对于 letsencrypt(sub.doamin.tld/*
->process.php?project=*
sub.domain.tld/*?q=test
->process.php?project=*&q=test
同时处理无限数量的查询参数
目前.htaccess
是:
RewriteEngine on
#serve actual file if viewing main page or doing https renewal
RewriteCond %{REQUEST_URI} ^?.+|/$ [OR]
RewriteCond %{REQUEST_URI} ^.well-known.*
RewriteRule (.*) - [L,QSA]
#redirect everything else to the processing script
RewriteCond %{REQUEST_URI} ^(w+)
RewriteRule /(w+) process.php?project=$1 [NC,L,QSA]
感谢您的帮助!
好吧,这实际上是一个复杂的问题,因为大多数时候,%{REQUEST_URI}
测试都是使用RewriteRule
本身完成的,所以我有点困惑,对此我很抱歉。
原来:
- %{REQUEST_URI} 包含前导斜杠
RewriteRule
的匹配部分没有
另外,请记住%{REQUEST_URI}
不包含查询字符串,如 Apache 手册中所述:
REQUEST_URI请求的 URI 的路径组件,例如"/index.html"。这尤其排除了查询字符串,该查询字符串可用作其自己的名为 QUERY_STRING 的变量。
因此,像RewriteCond %{REQUEST_URI} ^?.+
这样的规则几乎毫无用处,因为您永远不会有问号%{REQUEST_URI}
此外,这可能是最令人困惑的部分,当请求/
时,%{REQUEST_URI}
将包含已提供的实际索引文件。因此,如果您的DirectoryIndex
设置为index.php index.html
(按该顺序(,并且根文件夹中有一个index.html
文件,则{REQUEST_URI}
将index.html
。如果您有index.php
文件,它将是index.php
,但永远不会/
。
话虽如此,我们可以简化您的规则:
RewriteEngine on
RewriteCond %{REQUEST_URI} !^/(.well-known|index.php$)
RewriteRule (.+) process.php?project=%{REQUEST_URI} [QSA]
请注意,我在括号内添加了$
,以仅匹配index.php
之后的字符串字符的结尾,而不是.well-known
之后的字符串字符的结尾,因此.well-known
之后的任何内容也将匹配。
如果您有 html 索引,则需要将index.php
替换为index.html
。
最后,您不需要 2 条规则。最好只有一个并从中排除一些 URL。
PS:您还会注意到您不需要转义/
因为这不被视为正则表达式分隔符。
你只需要在你的.htaccess中这样一条规则:
RewriteEngine on
# skip files, directories and anything inside .well-known/ directory
RewriteRule ^(?!index.|process.php|.well-known)(.+)$ process.php?project=$1 [L,QSA,NC]