web-dev-qa-db-ja.com

.htaccessフレームワークなどを使用する場合、すべてのリクエストをパブリックディレクトリにリダイレクトします

この.htaccessコードを使用して、すべてのリクエストをパブリックディレクトリに送信します。

    <IfModule mod_rewrite.c>
        RewriteEngine On

        RewriteRule ^(.*)$ public/$1 [L]
    </IfModule>

サイト構造:

Public_html/
  app/
  public/
    app/
    css/
    index.php
  index.php

このコードは正常に機能しますが、ルートの既存のディレクトリにアクセスすると失敗します。

  • www.example.com/css-> public_html/public/css-正常に動作します
  • www.example.com/app-> public_html/app-OKではありません。public_html/public/appでなければなりません

既存のディレクトリを無視し、すべてをpublic dirに書き換える方法

5
DariusJu

このコードは正常に動作します

あなたは何か他のものを持っている必要があります...あなたが投稿したコードは、allリクエストの書き換えループ(500内部サーバーエラー)になりますか?

しかし、「既存のディレクトリを無視して、すべてをpublic dirに書き換える」ために特別なことをする必要もありません。繰り返しになりますが、何か他のものがここで起こっているのでしょうか?

ただし、書き換えループを回避するために必要なことは、「public」サブディレクトリにすでに書き換えられている場合に、「public」サブディレクトリへの書き換えを回避する条件を含めることです。例えば:

RewriteCond %{REQUEST_URI} !^/public/
RewriteRule (.*) public/$1 [L]

RewriteCondディレクティブなしで/something/public/somethingから/public/public/something/public/public/public/somethingなどに書き換えられます...

ちなみに、文字列全体を一致させる場合、アンカー(^$)は必要ないため、^(.*)$(.*)は同じです。

<IfModule mod_rewrite.c>

余談:サイトがmod_rewriteなしで「機能」することを意図していない限り、<IfModule...>ラッパーを削除する必要があります。

更新:

コメント:既存の.htaccessはlaravel開発者からのものです:

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    # Redirect Trailing Slashes If Not A Folder...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

OK、これはより理にかなっていますが、それは「問題」の一部でもあります。 anotherディレクティブを追加して動作することを期待することはできません。 with既存のディレクティブを使用する必要があります(それが意図の場合)。 mod_rewriteディレクティブの順序は重要です。

ドキュメントのルートにある既存のファイルとディレクトリを無視したいので、これはより複雑になります(質問どおり)。また、/publicサブディレクトリはおそらくプライベートに保つ必要があります。そうでなければ、単純にリダイレクトできます。 「末尾のスラッシュのリダイレクト」は、/publicディレクトリにリダイレクトできないため、少し注意が必要になります(明らかに非表示のディレクトリを公開するため)が、ディレクトリではなくディレクトリの存在をチェックする必要があります。ドキュメントのルート(現在の場所)。また、/publicディレクトリへの直接アクセスをブロックする(またはルートにリダイレクトする)必要もあります。

以下を試してください(RewriteEngineの後に、内部のmod_rewriteディレクティブのみが含まれます)。

# Prevent direct access to the "public" folder - redirect to root
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /public/
RewriteRule ^public/(.*) /$1 [R=302,L]

# Redirect Trailing Slashes If Not A Folder...
# - but look for the file in the "public" folder
#   (ensure we are not already in the "public" folder)
RewriteCond %{REQUEST_URI} !^/public/
RewriteCond %{DOCUMENT_ROOT}/public/$1 !-d
RewriteRule ^(.*)/$ /$1 [R=302,L]

# Rewrite "everything" to the "public" subdirectory if not already
# This ignores existing files/dirs in the document root
RewriteCond %{REQUEST_URI} ^/(.*)
RewriteRule !^public/ public/%1

# Handle Front Controller... (as before)
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]

以前の(誤った)301リダイレクトはブラウザによってキャッシュされているため、テストする前にブラウザのキャッシュを必ずクリアしてください。

302(一時)リダイレクトを301に変更します(正常に機能していることが確認できたら)。 (302はブラウザによってキャッシュされないため、テストが容易になります。)

3
MrWhite