9

次のように設定されている.htaccessファイルが原因で、ページがリダイレクトされません。

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

私はMVCフレームワークにこのセットアップを使用しているので、次のようなURLを取得しますが /controller/method/argument、/ forum / login.phpにリダイレクトすると、/forum/にカットされます。

これを例外として追加して、にリダイレクトできるようにするにはどうすればよいですか?/forum/login.php

/ 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>
4

2 に答える 2

24

まず、RewriteRuleの読み方を説明します。

最初の(または次の)RewriteRuleエントリから開始します。

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

最初のパラメーターは、要求されたURLに一致する正規表現です。^(.*)$すべてに一致し、後で使用できる変数内にこの「すべて」を格納します。

先行するRewriteCondエントリがある場合にのみ、次に評価されます。

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

$1RewriteRuleの最初の括弧内に一致するコンテンツへの参照です。これは、いくつかの明示的な名前を示す正規表現である2番目のパラメーターと比較され、!式を否定します。たとえば、このルールでは、正規表現が一致しない場合にのみRewriteRuleの実行が許可されます。この条件がtrueを返す場合、次の条件が調べられます。

RewriteCond %{REQUEST_FILENAME} !-f

要求されたファイル名がハードディスク上に実ファイルでない場合、この条件は真です。

RewriteCond %{REQUEST_FILENAME} !-d

要求されたファイル名が実際のディレクトリでない場合、この条件は真です。

これらすべての条件が真である場合(ANDで連鎖されている場合)にのみ、書き換えルールに戻ります。

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

この書き換えステップの結果は、2番目と3番目のパラメーターとして定義されます。$1は一致の内容と同様に再び使用され、パラメーターは、このルールが最初に一致した場合、最後のルール(L)になること、および書き換えターゲットで定義されたクエリ文字列がのクエリ文字列に追加されることを定義します。元のURL(QSA)。

批評:

MVCフレームワークの通常の書き換えは、可能な限りパフォーマンスを向上させようとします。書き換えを成功させるには、すべての書き換え条件を評価する必要があります。RewriteCondのいずれかがfalseを返した場合にのみ停止します。書き直されるすべてのリクエストは、CPUを集中的に使用するテストの対象となります。最初にRewriteRule正規表現、次に最初のRewriteCondの正規表現、続いてファイルシステムでファイルの存在を確認する2つのハードディスクテスト。

一方、最初のRewriteCondは不要のようです。特定の名前をテストし、見つかった場合は書き換えを中止します。「index.php」は既存のファイルであるため、2番目のRewriteCondによって検出される必要があります(そうでない場合、書き換えはどのように機能しますか)。「resources」で始まるものもすべて一致しますが、おそらく同じ理由で一致しないはずです。既存のリソースは2番目のRewriteCondによって検出されます。最後に「robots.txt」ファイルを追加します。ロボットがサイトをフェッチするときに404を回避したい場合は、空にすることをお勧めします。

クエリ文字列では何も変更しないため、[QSA]ディレクティブは必要ありません。

改善点:

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

最初のRewriteRuleは、要求されたパス全体と一致します。2つのRewriteCondは[OR]で接続されているため、trueを返す最初のRewriteCondはそれ以上の評価をキャンセルします。最初のRewriteCondは、要求されたファイルが存在するかどうかをテストします。存在する場合はtrueを返し、処理は最初のRewriteRuleに戻ります。対象となる式は「-」で、「書き換えない」という意味です。[L]は、書き換えルールのそれ以上の処理を停止します。したがって、最終的に、既存のファイルの場合、正規表現とファイルシステムのテストは1つだけになり、その後、この既存のファイルがブラウザーに送信されます。

ファイルが見つからなかった場合、最初のRewriteRuleとRewriteCondはトリガーされないため、[L]はプロセスを停止しません。したがって、2番目のRewriteRuleが実行されます。これは無条件であり、正規表現は以前と同じで、すべてに一致し、「index.php」に書き換えます。

/forum/login.phpを含むファイルが存在する場合、この書き換えではindex.phpは呼び出されません。

の代わりにRewriteRule ^.*$ index.php/$0 [L]解析を続行する場合は、秒をに変更できます。$_SERVER['PATH_INFO']$_SERVER['REQUEST_URI']

于 2012-10-12T20:31:50.407 に答える
2

これで試してください:

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

この:

# 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
于 2012-10-12T19:30:57.217 に答える