.htaccess: обслуживать статические файлы из публичного каталога без публичного URL-адреса, иначе переписать в index.php - PullRequest
0 голосов
/ 29 октября 2018

Ниже приведена структура каталогов моего сайта:

htdocs/
    My-Project/
        .htaccess
        public/
            css/
            img/
                img.jpg
            js/
        index.php
        ...(other stuff)

Я хочу использовать файл .htaccess, чтобы проверить, является ли запрошенный путь файлом в каталоге public / (аналогично обслуживанию статических файлов из каталога в выражении с помощью express.static) . Если да, обслужите это, иначе перешлите запрос к /index.php.

В основном мою проблему можно разделить на следующие подзадачи:

Подзадача1: обслуживать только файлы из общего каталога , иначе направлять в index.php
Подпроблема 2: обслуживать эти файлы из общедоступного каталога без необходимости (public) в URL-адресе

Таким образом, /My-Project/img/img.jpg следует переписать в /My-Project/public/img/img.jpg, но /My-Project/notexisting.file или /My-Project/test следует переписать в /My-Project/index.php.

До сих пор это была моя идея:

    RewriteEngine On

    #Block 1
    #Condition: File exists in public directory
    RewriteCond %{DOCUMENT_ROOT}/My-Project/public/$1 -f
    RewriteRule ^(.*)$ public/$1 [L]

    #Block 2
    #Condition: File doesn't exist in public directory
    RewriteCond %{DOCUMENT_ROOT}/My-Project/public/$1 !-f
    RewriteRule ^(.*)$ index.php [L,QSA]

Когда Block 1 стоит отдельно -> SubProblem2 решается, но как только добавляется Block 2 для решения SubProblem1, каждый запрос переписывается в index.php. Почему это происходит? Почему второй RewriteCond не работает должным образом?

Ответы [ 2 ]

0 голосов
/ 30 октября 2018

Второй RewriteCond не сработал, как я ожидал, потому что, как только Блок 1 переписывает Запрос, $ 1 в Блоке 2 не содержит той же информации, что и в Блоке 1.

Пример

Представьте, что у нас есть URI /My-Project/img/img.jpg.
В Block1 $1 будет img/img.jpg. Поскольку этот файл существует, RewriteCondition будет выполнено, и новый URI будет My-Project/public/img/img.jpg.
Теперь речь идет о Block2 : из-за переписанного URI здесь $1 определяется как public/img/img.jpg. Таким образом, RewriteCondition проверит, существует ли какой-либо существующий файл по URL MyProject/public/public/img/img.jpg. Конечно нет. Таким образом, RewriteCondition всегда будет выполняться, и каждый Запрос будет переписан в index.php независимо от какого-либо предыдущего перезаписи.

Решение

RewriteEngine On

RewriteCond %{DOCUMENT_ROOT}/My-Project/public/$1 -f
RewriteRule ^(.*)$ public/$1 [L]

RewriteCond %{THE_REQUEST} \s/My-Project/public/ [NC,OR]
RewriteCond $1 !^public/
RewriteRule ^(.*)$ index.php [L]
0 голосов
/ 29 октября 2018

Вот что я использую:

RewriteEngine On

# The following rule tells Apache that if the requested filename
# exists, simply serve it.

RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [NC,L]


# The following rewrites all other queries to index.php. The 
# condition ensures that if you are using Apache aliases to do
# mass virtual hosting, the base path will be prepended to 
# allow proper resolution of the index.php file; it will work
# in non-aliased environments as well, providing a safe, one-size 
# fits all solution.

RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}index.php [NC,L]

Обновите конфигурацию My Apache vhost, если вам нужно, это выглядит так:

<VirtualHost *:80>
    ServerName awesome.scot
    ServerAlias localhost
    DocumentRoot /var/www/html/public

    <Directory "/var/www/html">
            DirectoryIndex index.php
            FallbackResource /index.php
            Options -Indexes +FollowSymLinks
            AllowOverride FileInfo All
            Require all granted
    </Directory>
    ProxyPassMatch ^/(.*\.php)$ fcgi://php:9000/var/www/html/public/$1
</VirtualHost>

Затем в /etc/hosts я добавил 127.0.0.1 awesome.scot, поэтому теперь я захожу на свой сайт в браузере с помощью http://awesome.scot

Обратите внимание на две папки в vhost conf, одна - это корень сайта, другая - публичный каталог.

Если вы не включили vhosts, попробуйте! Раскомментируйте строку vhosts в вашем apache conf, затем перейдите в дополнительную папку и настройте vhost, затем перезапустите!

...