使用 .htaccess 强制删除 index.php

发布于 2024-11-14 07:12:24 字数 587 浏览 3 评论 0原文

我目前正在使用以下内容重写 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/ 这样的标题,它应该保留第二个索引。 php,因为它是 URL 的一部分。

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

谢谢。

I'm currently using the following to rewrite http://www.site.com/index.php/test/ to also work directly with http://www.site.com/test/, but I would like to not only allow the second version, I would like to FORCE the second version. If a user goes to http://www.site.com/index.php/test/ it should immediately reroute them to http://www.site.com/test/. index.php should never appear in a url. Stipulation: this should only apply to the first index.php. If I have a title like http://www.site.com/index.php/2011/06/08/remove-index.php-from-urls/ it should leave the second index.php, as it is part of the URL.

Current rule that allows but does not force:
#Remove index.php
RewriteCond $1 !^(index.php|images|css|js|robots.txt)
RewriteRule ^(.*)$ /index.php/$1 [L]

Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

<逆流佳人身旁 2024-11-21 07:12:24

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

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

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

As you wrote, if a user goes to http://www.site.com/index.php/test/ this rule will imediately reroute him to http://www.site.com/test/

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

I'm not sure if that is what you need as your current rewrite rule is opposite to mine.

一萌ing 2024-11-21 07:12:24

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

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

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 采取以下操作(假设我们请求 /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](不是子请求)标志同样不是一个选项,因为它根本不适用于我们的情况(请参阅 Apache RewriteRule 文档 关于它)
  • 设置环境变量不是一个选项(唉),因为在第 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

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

First (and wrong) answer - see below

You can accomplish a redirection with these directives (in this order):

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]

That will first redirect all the requests that begin with index.php to the corresponding shortened url, then silently serve index.php/etc with the second rule.

EDIT - Please read on!

In fact, the solution above generates an infinite redirection loop, because Apache takes the following actions (let's say we request /index.php/abc):

  1. first RewriteCond matches
  2. Apache redirects [R], that is, generates a new HTTP request, to /abc
  3. /abc fails first RewriteCond
  4. /abc matches second RewriteCond
  5. Apache does not redirect, but rewrites this URI (so it makes an "hidden" request), to /index.php/abc . We are again at point 1, that's a loop.

Please note...

  • By using the [L] (last rule) flag, we can only tell Apache not to process more rewrite rules, but only if the current rule matches. Since a new HTTP request is made, there is no information about how may redirection we have been through yet. So, any time one of the two matches, and in any case it generates a new request (=>loop)
  • Using the [C] (chain rules) flag is kinda pointless because it makes Apache process a rule only if the previous rule matches, while the two rules we have are mutually excluding.
  • Using the [NS] (not if subrequest) flag on rule #1 is again not an option because it aìsimply does not apply to our case (see Apache RewriteRule docs about it)
  • Setting env variables is not an option (alas), since a new request is made at pt 2, thus destroying all environment variables we set.

An alternative solution can be to rewrite e.g. /abc , to /index.php?path=abc. That is done by these rules (please, delete your RedirectMatch similar rule before adding these):

RedirectMatch ^/index\.php(/.*) $1

RewriteCond %{REQUEST_URI} !^/(index.php|images|css|js|robots.txt|favicon.ico)
RewriteRule ^(.+) /index.php?path=$1 [L,QSA]

I don't know the internals of CodeIgniter's scripts, but as most of the MVC scripts, it will read $_REQUEST['PATH_INFO'] to understand which page is requested. You could slightly modify the code that recognizes the page like this (I assumed that the page path is stored in the $page var):

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

This won't break the previous code and accomplish what you asked for.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文