-1

我目前正在使用以下内容进行重写http://www.site.com/index.php/test/以直接使用http://www.site.com/test/,但我不仅想允许第二个版本,我还想强制第二个版本。如果用户去http://www.site.com/index.php/test/它应该立即将他们重新路由到http://www.site.com/test/. index.php 永远不应出现在 url 中。规定:这应该只适用于第一个 index.php。如果我有类似的标题http://www.site.com/index.php/2011/06/08/remove-index.php-from-urls/,则应保留第二个 index.php,因为它是 URL 的一部分。

当前允许但不强制的规则:#Remove index.php RewriteCond $1 !^(index.php|images|css|js|robots.txt) RewriteRule ^(.*)$ /index.php/$1 [L]

谢谢。

4

2 回答 2

3

第一个(也是错误的)答案 - 见下文

您可以使用这些指令完成重定向(按此顺序):

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):

  1. 第一RewriteCond场比赛
  2. Apache 重定向 [R],即生成一个新的 HTTP 请求,以/abc
  3. /abc先失败RewriteCond
  4. /abc匹配第二RewriteCond
  5. 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']以了解请求的页面。您可以像这样稍微修改识别页面的代码(我假设页面路径存储在$pagevar 中):

$page = $_REQUEST['PATH_INFO'];
if(isset($_GET['path']) && strlen($_GET['path'])) $page = $_GET['path']; // Add this line

这不会破坏以前的代码并完成您所要求的。

于 2011-06-08T07:57:58.260 回答
2

正如您所写,如果用户使用http://www.site.com/index.php/test/此规则将立即将他重新路由到http://www.site.com/test/

RedirectMatch 301 /index.php/(.*)/$ /$1

我不确定这是否是您需要的,因为您当前的重写规则与我的相反。

于 2011-06-08T07:43:45.513 回答