【问题标题】:.htaccess mod_rewrite linking to wrong page.htaccess mod_rewrite 链接到错误的页面
【发布时间】:2012-03-09 02:46:34
【问题描述】:

我的 .htaccess 中有以下代码:

RewriteEngine On
RewriteRule ^/?([^/\.]+)/?$ $1.php [L]
RewriteRule ^/?([^/\.]+).php$ $1/ [R,L]

RewriteRule ^/?([^/\.]+)/?$ $1.php [L] 工作正常。这样做的目的是获取http://www.example.com/whatever 之类的网址,并将页面读取为http://www.example.com/whatever.php

但是,我想做的是获取像http://www.example.com/whatever.php 这样的网址并自动将其发送到http://www.example.com/whatever,因此是代码的第二行。但是,这是行不通的。它现在所做的是,一旦遇到以.php 结尾的链接,URL 就会变为http://localhost/C:/Sites/page/whatever/,并拉出403: Forbidden 页面。

我只想知道我能做什么,以便http://www.example.com/whatever.php 将被读取为http://www.example.com/whatever,并且如果在 URL 栏中输入http://www.example.com/whatever.php,它将自动重定向到http://www.example.com/whatever

这有意义吗?

编辑

好的,看来我不太清楚.. 基本上,我希望 /whatever/ 读作 whatever.php 而 URL 仍保持为 /whatever/,对吗?但是,如果 URL 是 /whatever.php,我希望它实际上 重定向 用户 URL 到 /whatever/,然后再次将其读取为 whatever.php。这可能吗?

【问题讨论】:

    标签: apache .htaccess mod-rewrite redirect clean-urls


    【解决方案1】:

    如果您的规则位于 .htaccess 文件中,您可以在匹配 URI 时省略前导斜杠:

    RewriteRule ^([^/\.]+)/?$ /$1.php [L]
    

    另请注意,目标中包含前导斜杠 (/$1.php),这可确保将 /whatever/ 重写为 /whatever.php。当您重定向时,如果您缺少这个前导斜杠,apache 会将文档根目录添加到它之前。因此 /whatever.php 被重定向到文档根目录 C:/Sites/page/whatever/。即使您包含前导斜杠,这也永远不会起作用,因为您将导致重定向循环:

    1. 在地址栏中输入“http://www.example.com/whatever.php”
    2. apache 将您重定向到“http://www.example.com/whatever/”
    3. apache 获取 URI whatever/ 并应用第一条规则,然后 URI 被重写为 /whatever.php
    4. URI 再次通过重写引擎
    5. URI /whatever.php 匹配第二条规则并将浏览器重定向到“http://www.example.com/whatever/”
    6. 重复步骤 3-5

    您需要添加一个实际请求是针对/whatever.php的条件:

    RewriteCond %{THE_REQUEST} ^(GET|POST|HEAD)\ /([^/\.]+)\.php
    RewriteRule ^ /%2/ [R,L]
    

    总的来说,您将拥有:

    RewriteEngine On
    RewriteRule ^([^/\.]+)/?$ /$1.php [L]
    RewriteCond %{THE_REQUEST} ^(GET|POST|HEAD)\ /([^/\.]+)\.php
    RewriteRule ^ /%2/ [R,L]
    

    【讨论】:

    • 谢谢乔恩!之前试过这段代码,好像没用,今天早上又试了一次,你知道吗,它有效!看来我的.htaccess 只是有一点时间......不过,非常感谢你!
    【解决方案2】:

    您正在逐目录上下文中进行相对路径替换(.htaccess 是逐目录上下文)。这需要RewriteBase。当 URL 映射到路径时,每个目录的重写在处理的后期完成。但是重写必须产生一个URL,它会被再次处理。我认为如果没有 RewriteBase 来提供 URL 前缀,你最终会得到一个文件系统前缀而不是 URL。这可能就是你得到C:/Sites 的原因。试试RewriteBase。但是在正确的RewriteBase 指定正确的URL 前缀后,要在相对重写部分前面加上,恐怕你会有重写循环,因为你将whatever.php 重写为whatever;和whateverwhatever.php

    参考:http://httpd.apache.org/docs/current/rewrite/tech.html

    【讨论】:

    • 干杯 Kaz,我认为这会产生很大的不同。但是,我并没有将whatever 更多地重定向whatever.php,我想,只是在它看到whatever 时告诉它,从whatever.php 中提取信息。有什么办法可以做到,如果它看到whatever,它将从whatever.php中提取,但url仍将显示whatever,但如果url是whatever.php,它将重定向到whatever ?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多