我正在尝试在我的 Web 应用程序中获取.htaccess
文件RewriteRule
。我需要一个双重规则来匹配可能发生的两种 URL 格式:
规则 1(下面未评论,就像一个魅力(
http://example.com/whatever -> /index.php?page=whatever&
http://example.com/whatever/ -> /index.php?page=whatever&
http://example.com/whatever/?test=me -> /index.php?page=whatever&test=me
规则 2(在下面注释掉并且不起作用,但应该像这样工作(
http://example.com/api/ -> index.php?page=api&func=
http://example.com/api/whateverelse -> index.php?page=api&func=whateverelse
服务器上不存在文件夹/api/
,通过阅读文档,L
参数应防止解析更多规则。然而,如果我取消评论^/api/(.*)$
,我会得到 404 回复。
目标是,如果解析了第一个规则,则省略第二个规则,目标是第一个规则实际有效。
有人可以在这里指出我正确的方向吗?
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
#RewriteRule ^/api/(.*)$ //index.php?page=api&func=$1 [NC,L]
RewriteRule ^/?([^/]+)/?$ //index.php?page=$1&%{QUERY_STRING} [NC,L]
我试图通过添加以下内容来调试它:LogLevel alert rewrite:trace6
但这在.htaccess
中是不允许的,我无法直接访问服务器配置文件。
#RewriteRule ^/api/(.*)$ //index.php?page=api&func=$1 [NC,L]
这不起作用,因为.htaccess
与RewriteRule
模式匹配的 URL 路径不以斜杠开头。您已在正则表达式中包含斜杠前缀,因此它永远不会匹配。
在以下规则中,斜杠前缀是可选的,带有?
量词,即。^/?
- 所以它会匹配。(只有在服务器上下文中使用指令时才需要斜杠前缀。通过使其"可选",它将在任一中工作。
如果仅使用.htaccess
则可以从RewriteRule
模式中完全删除斜杠前缀。
例如:
RewriteRule ^api/(.*) /index.php?page=api&func=$1 [NC,L]
附加说明...
- 无需在正则表达式中反斜杠转义斜杠,因为它们没有特殊含义。(Apache 使用空格作为参数分隔符。
- 不确定替换字符串上的双斜杠前缀是做什么用的?
//index.php
.这里最多只能有一个斜杠,或者根本没有内部重写的斜杠(并且index.php
文件与.htaccess
文件位于同一目录中(。(双斜杠仍然"有效",只是因为 Apache 在将 URL 映射到文件系统时减少了多个斜杠的实例。 RewriteCond
指令仅适用于后面的第一个RewriteRule
指令,因此您可能需要对第二个规则重复这些指令。(或者反转逻辑并在请求映射到文件/目录时停止处理?但是,这可能取决于您文件中的其他指令。如果没有以/api
开头的物理文件,则可以从该规则中删除条件。
您无需- 手动将
QUERY_STRING
追加到替换项。这就是QSA
(查询字符串追加(标志的用途。当请求中不存在查询字符串时,QSA
标志还将避免最后出现杂散&
。 - 最后一个规则不需要
NC
标志。"api"规则也可能不需要它,除非可能需要/API
或/ApI
等 - 但应避免这种情况。
所以,把这些放在一起,我们有....
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^api/(.*) /index.php?page=api&func=$1 [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ /index.php?page=$1 [QSA,L]