简体   繁体   English

特定文件的mod_rewrite异常

[英]mod_rewrite exception for a specific file

My page is not redirecting as it should due to my .htaccess file which is set as: 我的页面没有重定向,因为我的.htaccess文件设置为:

RewriteEngine on  
RewriteCond $1 !^(index\.php|resources|robots\.txt)  
RewriteCond %{REQUEST_FILENAME} !-f  
RewriteCond %{REQUEST_FILENAME} !-d  
RewriteRule ^(.*)$ index.php/$1 [L,QSA]   

I use this setup for my MVC Framework so i get urls like /controller/method/argument however when I redirect to /forum/login.php it cuts to /forum/. 我将这个设置用于我的MVC框架,所以我得到像/controller/method/argument这样的网址,但是当我重定向到/forum/login.php时它切换到/ forum /。

How can I add this as an exception so that i will be able to redirect to /forum/login.php 如何将此作为例外添加,以便我能够重定向到/forum/login.php

I found another .htaccess in my /forum/ directory could this be causing the problem as well? 我发现我的/ forum /目录中的另一个.htaccess也可能导致问题?

# BEGIN PunBB

<IfModule mod_rewrite.c>
    # MultiViews interfers with proper rewriting
    Options -MultiViews

    RewriteEngine On

    # Uncomment and properly set the RewriteBase if the rewrite rules are not working properly
    #RewriteBase /

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . rewrite.php [L]
</IfModule>

First I'll tell you how to read your RewriteRule: 首先,我会告诉你如何阅读你的RewriteRule:

You start with the first (or next) RewriteRule entry: 您从第一个(或下一个)RewriteRule条目开始:

RewriteRule ^(.*)$ index.php/$1 [L,QSA]

The first parameter is a regular expression that can match your requested URL. 第一个参数是可以匹配您请求的URL的正则表达式。 ^(.*)$ matches everything, and stores this "everything" inside a variable that can be used later. ^(.*)$匹配所有内容,并将此“所有内容”存储在稍后可以使用的变量中。

Only if there are preceding RewriteCond entries, they are evaluated next: 只有当前有RewriteCond条目时,才会对它们进行评估:

RewriteCond $1 !^(index\\.php|resources|robots\\.txt)

$1 is a reference to the content matched inside the first parentheses of RewriteRule. $1是对RewriteRule的第一个括号内匹配的内容的引用。 This is compared to the second parameter, which is a regular expression stating several explicit names, and the ! 这与第二个参数进行比较,第二个参数是一个表示几个显式名称的正则表达式,并且! negates the expression, eg this rule allows execution of the RewriteRule only if the regex does not match. 否定表达式,例如,只有当正则表达式不匹配时,此规则才允许执行RewriteRule。 If this condition returns true, the next condition will be looked at. 如果此条件返回true,则将查看下一个条件。

RewriteCond %{REQUEST_FILENAME} !-f

If the requested filename is no real file on the harddisk, this condition is true. 如果请求的文件名不是硬盘上的真实文件,则此条件为真。

RewriteCond %{REQUEST_FILENAME} !-d

If the requested filename is no real directory, this condition is true. 如果请求的文件名不是真实目录,则此条件为真。

Only if all these conditions are true (they are chained together with AND), we come back to the rewrite rule: 只有当所有这些条件都成立时(它们与AND链接在一起),我们才会回到重写规则:

RewriteRule ^(.*)$ index.php/$1 [L,QSA]

The result of this rewrite step is defined as the second and third parameter. 该重写步骤的结果被定义为第二和第三参数。 $1 is used again as with the content of the match, and the parameters define that this rule, if initially matched, will be the last rule (L), and that any query string defined in the rewrite target will be appended to any query string in the original URL (QSA). 再次使用$1作为匹配的内容,并且参数定义此规则(如果最初匹配)将是最后一个规则(L),并且重写目标中定义的任何查询字符串将附加到任何查询字符串在原始网址(QSA)中。

Critique: 批判:

The usual rewriting for MVC frameworks try to be as performant as possible. MVC框架的通常重写尝试尽可能高效。 Your rewrite conditions all have to be evaluated for a successful rewrite. 您的重写条件都必须进行评估才能成功重写。 The will stop only if any of the RewriteCond return false. 只有当任何RewriteCond返回false时,才会停止。 Every request that gets rewritten is subject to plenty of cpu intensive tests. 每个被重写的请求都需要进行大量的cpu密集测试。 First the RewriteRule regex, then the regex in the first RewriteCond, followed by two harddisk tests on the filesystem for file existance. 首先是RewriteRule正则表达式,然后是第一个RewriteCond中的正则表达式,然后对文件系统进行两次硬盘测试,以确定是否存在文件。

On the other hand, the first RewriteCond seems to be unnecessary. 另一方面,第一个RewriteCond似乎是不必要的。 It tests for certain names, and if found, aborts the rewriting. 它测试某些名称,如果找到,则中止重写。 "index.php" should be detected by the second RewriteCond, because it is an existing file (how would the rewriting work if not). “index.php”应该被第二个RewriteCond检测到,因为它是一个现有文件(如果不是,那么重写将如何工作)。 Anything starting with "resources" will also be matched, but probably shouldn't for the same reasons: Existing resources will be found by the second RewriteCond. 任何以“资源”开头的东西也会匹配,但可能不应该出于同样的原因:第二个RewriteCond会找到现有资源。 Last the "robots.txt" file. 最后是“robots.txt”文件。 It is always a good idea to have one, possibly emtpy if you want to avoid 404 when robots fetch your site. 如果你想在机器人获取你的网站时避免使用404,那么拥有一个可能是一个好主意。

As you are not changing anything in the query string, the [QSA] directive is not needed. 由于您没有更改查询字符串中的任何内容,因此不需要[QSA]指令。

Improvements: 改进:

RewriteEngine on  
RewriteCond %{REQUEST_FILENAME} -f [OR] 
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [L]  
RewriteRule ^.*$ index.php [L]

The first RewriteRule will match the whole requested path. 第一个RewriteRule将匹配整个请求的路径。 The two RewriteCond are connected with [OR], so the first RewriteCond that returns true will cancel further evaluation. 两个RewriteCond与[OR]连接,因此返回true的第一个RewriteCond将取消进一步的评估。 The first RewriteCond tests if the requested file exists. 第一个RewriteCond测试所请求的文件是否存在。 If it exists, it returns true, and the processing returns to the first RewriteRule. 如果存在,则返回true,处理返回到第一个RewriteRule。 The target expression is "-", which means "do not rewrite". 目标表达式为“ - ”,表示“不重写”。 The [L] stops further processing of rewrite rules. [L]停止进一步处理重写规则。 So in the end, for an existing file we only have one regex and one filesystem test, and after that, this existing file will be sent to the browser. 所以最后,对于现有文件,我们只有一个正则表达式和一个文件系统测试,之后,这个现有文件将被发送到浏览器。

If no file was found, the first RewriteRule and RewriteCond will not trigger, so the [L] there will not stop the process. 如果没有找到文件,第一个RewriteRule和RewriteCond将不会触发,因此[L]不会停止该过程。 So the second RewriteRule is executed. 所以第二个RewriteRule被执行了。 This one is unconditional, and the regex is the same as before, matching everything, and rewriting it to "index.php". 这个是无条件的,正则表达式与之前相同,匹配所有内容,并将其重写为“index.php”。

This rewriting will not call your index.php if any file exists, including /forum/login.php. 如果存在任何文件,则此重写不会调用index.php,包括/forum/login.php。

You can change the second to RewriteRule ^.*$ index.php/$0 [L] if you do want to continue parsing $_SERVER['PATH_INFO'] instead of $_SERVER['REQUEST_URI'] . 如果你想继续解析$_SERVER['PATH_INFO']而不是$_SERVER['REQUEST_URI']你可以将第二个更改为RewriteRule ^.*$ index.php/$0 [L] $_SERVER['REQUEST_URI']

Try with this: 试试这个:

RewriteEngine on  
RewriteCond $1 !^(index\.php|forum|resources|robots\.txt)  
RewriteCond %{REQUEST_FILENAME} !-f  
RewriteCond %{REQUEST_FILENAME} !-d  
RewriteRule ^(.*)$ index.php/$1 [L,QSA]   

And this: 还有这个:

# BEGIN PunBB

# ----------------------------------------------------------------------
# Start rewrite engine
# ----------------------------------------------------------------------

<IfModule mod_rewrite.c>
    # MultiViews interfers with proper rewriting
    Options -MultiViews

    RewriteEngine On

    # Uncomment and properly set the RewriteBase if the rewrite rules are not working properly
    RewriteBase /forum/

    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . rewrite.php [L]
</IfModule>


# ----------------------------------------------------------------------
# Better website experience for IE users
# ----------------------------------------------------------------------

# Force the latest IE version, in various cases when it may fall back to IE7 mode
# github.com/rails/rails/commit/123eb25#commitcomment-118920
# Use ChromeFrame if it's installed for a better experience for the poor IE folk

<IfModule mod_setenvif.c>
    <IfModule mod_headers.c>
        BrowserMatch MSIE ie
        Header set X-UA-Compatible "IE=Edge,chrome=1" env=ie
    </IfModule>
</IfModule>

<IfModule mod_headers.c>
    # Because X-UA-Compatible isn't sent to non-IE (to save header bytes),
    # We need to inform proxies that content changes based on UA
    Header append Vary User-Agent
    # Cache control is set only if mod_headers is enabled, so that's unncessary to declare
</IfModule>


# ----------------------------------------------------------------------
# UTF-8 encoding
# ----------------------------------------------------------------------

# Use UTF-8 encoding for anything served text/plain or text/html
AddDefaultCharset utf-8

# Force UTF-8 for a number of file formats
AddCharset utf-8 .html .css .js .xml .json .rss


# ----------------------------------------------------------------------
# A little more security
# ----------------------------------------------------------------------

# Do we want to advertise the exact version number of Apache we're running?
# Probably not.
## This can only be enabled if used in httpd.conf - It will not work in .htaccess
# ServerTokens Prod


# "-Indexes" will have Apache block users from browsing folders without a default document
# Usually you should leave this activated, because you shouldn't allow everybody to surf through
# every folder on your server (which includes rather private places like CMS system folders).
<IfModule mod_autoindex.c>
    Options -Indexes
</IfModule>

# END PunBB

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM