Обслуживание многоязычного статического контента через Apache для веб-приложения
У меня есть многоязычный статический контент, который я хочу использовать через Apache. Эти файлы являются кеш-файлами, сгенерированными JIT приложением, поэтому, если они там есть, их следует обслуживать, в противном случае отправьте запрос приложению, которое создаст их на месте.
Я указываю язык через HTTP Accept-Language
заголовок, который может быть hr
, en
, но также en-US,en;q=0.5
(поэтому нет простого "добавления языка к имени файла для продолжения").
URL-адреса как:
в моем приложении у меня есть папка с точно таким же макетом, добавляется только язык, например:
/static/homepage.html.en
/static/homepage.html.hr
/static/script.js.en
/static/script.js.hr
Я понял, что для Accept-Language
разбор мне нужен mod_negotiation
и придумал это:
# Alias
/static /www/app/var/cache/static
<Directory /www/app/var/cache/static>
FileETag MTime Size
Options MultiViews
AddLanguage hr .hr
AddLanguage en .en
<IfModule mod_negotiation.c>
LanguagePriority en hr
</IfModule>
ErrorDocument 404 /index.php
</Directory>
Это работает, но только для первого промаха. Так
- если я запрашиваю http://www.example.com/static/homepage.html,
Accept-Language: hr
, это создастhomepage.html.hr
(правильный) - Теперь, если я запрашиваю http://www.example.com/static/homepage.html,
Accept-Language: en
, он не выбрасывает 404 (с помощью которого запускается процесс создания файла), а вместо этого служитhomepage.html.hr
(что достаточно близко для Apache, но неверно для меня).
Решения, которые я вижу для этого:
- обслуживание статических файлов через PHP (чего я бы хотел избежать)
- с помощью
mod_rewrite
(но я скучаю поAccept-Language
разбор части) - предварительная генерация всех файлов (что кажется огромным перетаскиванием)
Есть ли четвертый путь или я что-то упустил?
Изменить: полное решение в соответствии с принятым ответом
# Alias
/static /www/app/var/cache/static
<Directory /www/app/var/cache/static>
FileETag MTime Size
Options MultiViews
AddLanguage hr .hr
AddLanguage en .en
<IfModule mod_negotiation.c>
LanguagePriority en hr
ForceLanguagePriority none
</IfModule>
ErrorDocument 404 /index.php
ErrorDocument 406 /index.php
</Directory>
2 ответа
Возможно, ForceLanguagePriority имеет значение "Prefer" или "Prefer Fallback". Если вместо этого установить "None", Apache сгенерирует ошибку 406, которую можно настроить для запуска того же процесса генерации файлов, что и 404.
С модом переписать вы можете сделать это так:
<Directory /www/app/var/cache/static>
RewriteEngine On
RewriteCond %{HTTP:Accept-Language} ^pl.*$ [NC]
RewriteCond %{REQUEST_URI} ^.*(js|css)$ [NC]
RewriteRule ^(.*)$ %{REQUEST_URI}.pl [L,R=302]
RewriteCond %{HTTP:Accept-Language} ^hr.*$ [NC]
RewriteCond %{REQUEST_URI} ^.*(js|css)$ [NC]
RewriteRule ^(.*)$ %{REQUEST_URI}.hr [L,R=302]
RewriteCond %{HTTP:Accept-Language} ^en.*$ [NC]
RewriteCond %{REQUEST_URI} ^.*(js|css)$ [NC]
RewriteRule ^(.*)$ %{REQUEST_URI}.en [L,R=302]
# (...) do it for all languages
ErrorDocument 404 /index.php
</Directory>