通过htaccess规则令人惊讶地重写URL

时间:2014-02-25 09:38:26

标签: .htaccess mod-rewrite

我把我的问题归零了,我有一个具体的问题。

如果我在.httaccess输入我的网址,index2.php中只有以下代码可以调用www.mysite.com/url2

RewriteEngine On
RewriteCond %{REQUEST_URI} (.html|.htm|.feed|.pdf|.raw)$  [NC]
RewriteRule (.*) index2.php [L]

我也在http://www.regextester.com进行了测试,不应该用index2.php替换它:

enter image description here

最后,我希望此规则跳过以/ url2或/ url2 /*开头的任何网址。

编辑:我已对此问题进行了屏幕录制:http://screenr.com/BBBN

2 个答案:

答案 0 :(得分:1)

您在.htaccess

中有这个
RewriteEngine On
RewriteCond %{REQUEST_URI} (.html|.htm|.feed|.pdf|.raw)$  [NC]
RewriteRule (.*) index2.php [L]

它做什么?它会重写任何以 html htm Feed pdf 原始结尾的内容到index2.php。因此,如果您获得结果,因为您的网址以这些扩展名结尾,那么有两种可能的答案:

  1. 在上层目录(或服务器配置文件)中的.htaccess中有另一个重写规则导致重写URL。
  2. 您的网址实际上以这些扩展名结尾。请记住,您在地址栏中输入的内容将被编辑和重写。例如,如果在地址栏中输入www.mysite.com/url2并且该文件在服务器上不存在,则服务器将尝试加载正确的错误文档。因此,如果您的错误文档为/404.html,则最终会将其重写为index2.php

  3. <强>更新: 我认为就是这样。在文档根目录中创建名为404.php的文件。在您的主.htaccess内(在您的文档根目录中),请输入:

    ErrorDocument 404 /404.php
    

    删除所有其他ErrorDocument指令。 在404.php内,把它放在:

    <?php
        echo 'From 404.php file';
    ?>
    

    背后的逻辑:

    当你在mod_rewrite中有一个奇怪的行为时,根据我的经验,最好的解决方案是使用重写日志。要启用重写日志,请将其放在您可能选择的virtualhost或其他服务器配置指令中:

    RewriteLogLevel 9
    RewriteLog "logs/RewriteLog.log"
    

    小心:上面的代码将启用重写日志并以最高级别开始记录(记录所有内容)。它会降低您的服务器速度,日志文件将变得非常快。只在您的开发服务器上执行此操作。

    解释:当您尝试访问www.mysite.com/url2时,Apache会将您的URL提供给重写模块。重写模块检查RewriteRule是否适用于您的URL。因为您有一个规则并且它不适用于您的URL,它会尝试加载普通文件。但是这个文件没有退出。因此,Apache将执行下一步,显示正确的错误消息。设置自定义错误文件时,Apache将针对新地址运行测试。例如,如果错误文档为 /404.html ,则Apache会检查您的规则是否适用于 /404.html 。既然如此,它将重写它。

    需要记住的是,每当URL发生变化时,apache都会这样做,无论是否通过重写模块进行更改!

答案 1 :(得分:0)

如果这是唯一的规则,则列出should work as you expect的规则。事实是理论很有趣,但显然它没有按预期工作。请注意.将匹配任何字符。如果你想匹配句号/句号的完整字符,你需要将其转义。这就是我使用\.(html|htm|feed|pdf|raw)$代替(.html|.htm|.feed|.pdf|.raw)$的原因。


如果网址以/ url2开头,您可以添加另一个不匹配的RewriteCond,如下所示。如果有许多网址不匹配,这可能不是一个可行的解决方案。

RewriteCond %{REQUEST_URI} !^/url2
RewriteCond %{REQUEST_URI} \.(html|htm|feed|pdf|raw)$ [NC]
RewriteRule (.*) index2.php [L]

为了更好地了解正在发生的事情,您可以将规则更改为类似的内容。现在只需在网址栏中输入您不想匹配的网址,并在重定向发生后检查网址栏。在url-parameter中,您现在可以看到实际触发此规则匹配的url。 This screencast向您展示了一个类似的版本,该版本使用了一个偷偷摸摸的重写文件,正在使用该网址。

#A way of finding out what is -actually- matched
RewriteCond %{REQUEST_URI} \.(html|htm|feed|pdf|raw)$ [NC]
RewriteCond %{REQUEST_URI} !/foo
RewriteRule (.*) /foo?url=$1 [R,L]

您可以决定匹配%{THE_REQUEST}变量。这将始终包含请求本身。如果其他内容正在重写url,则此变量不会更改,这意味着您可以使用此变量覆盖任何更改。确保网址不匹配。你会得到类似下面的东西。可以找到一个示例截屏视频here

#If it doesn't end on .html/htm/feed etc, this one won't match
RewriteCond %{THE_REQUEST} ^(GET|POST)\ /.*\.(html|htm|feed|pdf|raw)\ HTTP [NC]
RewriteCond %{REQUEST_URI} !^/index2\.php$
RewriteRule (.*) /index2.php [L]