第一个(也是错误的)答案 - 见下文
您可以使用这些指令完成重定向(按此顺序):
RewriteCond %{REQUEST_URI} ^index.php
RewriteRule ^index\.php/(.+)$ /$1 [R,L]
RewriteCond $1 !^(index.php|images|css|js|robots.txt)
RewriteRule ^(.*?)$ /index.php/$1 [L]
这将首先将index.php
所有以相应缩短的 url开头的请求重定向,然后index.php/etc
使用第二条规则静默服务。
编辑 - 请继续阅读!
实际上,上面的解决方案会生成一个无限重定向循环,因为 Apache 采取了以下操作(假设我们 request /index.php/abc
):
- 第一
RewriteCond
场比赛
- Apache 重定向 [R],即生成一个新的 HTTP 请求,以
/abc
/abc
先失败RewriteCond
/abc
匹配第二RewriteCond
- Apache 不会重定向,而是将此 URI 重写(因此它发出“隐藏”请求),以
/index.php/abc
. 我们又回到了第 1 点,这是一个循环。
请注意...
- 通过使用 [L](最后一条规则)标志,我们只能告诉 Apache 不要处理更多的重写规则,但前提是当前规则匹配。由于发出了一个新的 HTTP 请求,因此还没有关于我们如何进行重定向的信息。因此,任何时候两者之一匹配,并且在任何情况下它都会生成一个新请求(=>循环)
- 使用 [C](链式规则)标志有点没有意义,因为它使 Apache 仅在前一个规则匹配时才处理规则,而我们拥有的两个规则是相互排斥的。
- 在规则 #1 上使用 [NS] (not if subrequest) 标志再次不是一个选项,因为它根本不适用于我们的案例(参见Apache RewriteRule 文档)
- 设置环境变量不是一个选项(唉),因为在 pt 2 发出了一个新请求,因此破坏了我们设置的所有环境变量。
另一种解决方案可以是重写,例如/abc
,改写为/index.php?path=abc
. 这是由这些规则完成的(请在添加这些规则之前删除您的 RedirectMatch 类似规则):
RedirectMatch ^/index\.php(/.*) $1
RewriteCond %{REQUEST_URI} !^/(index.php|images|css|js|robots.txt|favicon.ico)
RewriteRule ^(.+) /index.php?path=$1 [L,QSA]
我不知道 CodeIgniter 脚本的内部结构,但与大多数 MVC 脚本一样,它会读取$_REQUEST['PATH_INFO']
以了解请求的页面。您可以像这样稍微修改识别页面的代码(我假设页面路径存储在$page
var 中):
$page = $_REQUEST['PATH_INFO'];
if(isset($_GET['path']) && strlen($_GET['path'])) $page = $_GET['path']; // Add this line
这不会破坏以前的代码并完成您所要求的。