Как мы можем перенаправить на новый статический контент HTML с Apache и вернуться к более старой версии PHP на основе CMS, если не найден? (nginx try_files) - PullRequest
3 голосов
/ 28 марта 2019

Проблема:

Мы находимся в процессе замены старого веб-сайта на основе PHP (на основе Statamic v1) на HTML-версию SSG, созданную с помощью Gatsby.

Проблема в том, что должна быть заменена только часть существующих страниц, в то время как пространство элементов и страницы /login и /contact должны быть сохранены.

Так что мне интересно, как мне адаптировать текущую конфигурацию .htaccess к новой версии , которая сначала смотрит , для нового статического содержимого, найденного в определенном каталоге (public/), или, если нет, отступить к старый index.php?path= метод.

Примечание:

С nginx это будет сделано с помощью директивы try_files Итак, этот вопрос как-то связан с: https://serverfault.com/questions/290784/what-is-apaches-equivalent-of-nginxs-try-files
но я абсолютно не понимаю вещи balancer://app_cluster ..

Контекст:

Вот упрощенное представление каталогов, поскольку они должны обслуживаться Apache:

www/
├── index.php
├── (... more CMS files)
└── public
    ├── index.html
    ├── main.js
    ├── robots.txt
    ├── img
    │   ├── intro.jpg
    │   ├── logo.svg
    │   └── table.png
    ├── about
    │   └── index.html
    └── staff
        └── index.html

Все в public/ должно быть подано сначала
без указания /public в конечном URL:

URL : /img/intro.jpg => /public/img/intro.jpg (rewritten as /img/intro.jpg)

И каждый URL, соответствующий странице /index.html, должен быть переписан без него:

URL : '' or '/' => /public/index.html (rewritten as '')
URL : /staff or /staff/ => /public/staff/index.html (rewritten as /staff)

Каждый не найденный файл перенаправляется на /index.php?path=..., как уже было сделано.

Вопрос

Возможно ли только с Apache без пересортировки в два отдельных субдомена и virtual_hosts .. разделить 2 источника?
Я думаю, что да, учитывая невероятные способности Apache, но так как я более привык к способам работы с nginx, мне действительно нужна ваша помощь здесь !! :)

Текущая конфигурация

(не спрашивайте меня почему)

# Turn on the Rewrite Engine
RewriteEngine On

# PERMANENT HTTPS REDIRECTION
RewriteCond %{REQUEST_SCHEME} =http
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]

# If you're running in a subfolder (like http://example.com/statamic),
# add that here. E.g. /statamic/
RewriteBase /

# Protect your system files from prying eyes
RewriteRule ^(_app) - [F,L]
RewriteRule ^(_config) - [F,L]
RewriteRule ^(_content) - [F,L]
RewriteRule ^(_logs) - [F,L]
RewriteRule ^(.*)?\.yml$ - [F,L]
RewriteRule ^(.*)?\.yaml$ - [F,L]
RewriteRule ^(.*/)?\.git+ - [F,L]

# This will prevent all .html files from being accessed.
# You may want to remove this line if you want to serve
# static files outside of Statamic
# RewriteRule ^(.*)?\.html$ - [F,L]

# Remove trailing slashes from your URL
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\/(\?.*)?$ $1$2 [R=301,L]

# Remove the index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]

# No Cache.. because of user's logged/not logged output differences
# Header set Cache-Control "no-cache"

# Enable expirations
ExpiresActive On

# Default directive
ExpiresDefault "modification"

ExpiresByType text/html "modification"

# # My favicon
ExpiresByType image/x-icon "access plus 1 year"

# # Images
ExpiresByType image/gif "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/svg+xml "access plus 1 month"

# CSS
ExpiresByType text/css "access plus 1 month"

# Javascript
ExpiresByType application/javascript "access plus 1 month"

# COMPRESS JSON
AddOutputFilterByType DEFLATE text/html
AddOutputFilterByType DEFLATE text/css
AddOutputFilterByType DEFLATE text/javascript
AddOutputFilterByType DEFLATE application/javascript
AddOutputFilterByType DEFLATE application/json

1 Ответ

3 голосов
/ 08 апреля 2019

Если я правильно понимаю, их ключевое требование состоит в том, чтобы обслуживать статический контент в public/, если он существует, и если нет, передать запрос в index.php.

Это требование относительно легко выполнить.Порядок правил важен, так как они применяются последовательно для каждого входящего запроса.Сначала мы можем выполнить тест для контента public/, поэтому, если он там существует, мы преимущественно вернем его и остановим обработку.Если запрос не соответствует этому тесту, обработка будет продолжена до перенаправления index.php.

RewriteEngine On

# If the requested file or directory exists in public/, internally redirect
# there (internally means no actual new http request, and the URL in the
# browser does not change).  Use OR flag to OR the 2 conditions, instead of
# the usual implicit AND.
RewriteCond %{DOCUMENT_ROOT}/public%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/public%{REQUEST_URI} -d
RewriteRule ^.*$ public/%{REQUEST_URI} [L]

# If the requested file does not exist, and is not a directory, pass the
# request to index.php, appending any query string.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]

Обратите внимание, что вы упомянули:

Каждый не найденный файл перенаправляется в /index.php? path = ... как уже было сделано.

Просто чтобы прояснить, это не на самом деле то, что .htaccess, который вы включили, делает сейчас.Это правило просто передает запрос в index.php, без параметра path (включая все существующие параметры, которые уже есть в запросе).Ваш index.php может получить доступ - и, конечно, уже получает доступ - к реальному запрошенному пути, используя $_SERVER переменные.Но если вы действительно хотите теперь добавить путь к запросу, как вы описываете, вам нужно изменить это правило на что-то вроде:

RewriteRule ^(.*)$ index.php?path=$1 [QSA,L]

Еще одно замечание - есть много посторонних вещейкак в вопросе, так и в .htaccess, который, как мне кажется, смущает проблему, и, возможно, именно поэтому вы не получили здесь хорошего ответа.

...