我有这段代码:
RewriteEngine on
RewriteRule api/v2/([^/]+)/?$ api/v2/api.php?request=$1 [L]
RewriteRule api/v2 api/v2/api.php [L]
RewriteRule ^$ handler.php?request=main [L]
RewriteRule ^(.*)$ handler.php?request=$1 [L]
...在根目录下的.htaccess文件中。其目的是用https://example.org/hello/world
重写https://example.org/handler.php?request=hello/world
。
每当我导航到现有目录时,它都会在末尾添加?request
。例如:如果我导航到https://example.org/foo
(foo是目录),它将重定向到https://example.org/foo/?request=foo
。
为什么会发生这种情况,我该如何解决?
更新1
我添加了以下几行,它们可以根据需要使用:
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !(/$|\.)
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L]
但这引起了另一个问题,当我去handler.php和echo $_GET["request"]
时,我得到handler.php
。
更新2
我已将.htaccess
简化为此:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !(/$|\.)
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L]
RewriteRule ^(.*)$ handler.php?request=$1 [L]
但仍有同样的问题,$_GET["request"]
会返回handler.php
更新3
我为这个问题增加了一笔赏金,更多的是出于好奇而不是现在的任何事情。
答案 0 :(得分:1)
我会以相反的方式使用它。 如果请求的文件不是,则现有文件或目录然后会根据请求将重写文件设置为处理程序文件。
测试了以下代码,似乎可以正常工作。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ handler.php?request=$1 [L]
</IfModule>
<强> handler.php 强>
var_dump($_GET);
输出:
array(1) { ["request"]=> string(11) "hello/world" }
http://localhost/example(确实存在)
输出:
Directory parent
http://localhost/a.php(确实存在)
输出:
File a exists //Something that is written in a.php
答案 1 :(得分:1)
问题在于您的规则是以循环模式重写请求,因为无条件规则和catch-all模式将目标文件 handler.php 重写为自身。
您需要修复规则的模式,使其与目标文件不匹配。
rewrite engine on
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_URI} !(/$|\.)
RewriteRule (.*) %{REQUEST_URI}/ [R=301,L]
RewriteRule ^((?!handler.php).*)$ handler.php?request=$1 [L]