Назад | Перейти на главную страницу

Блок местоположения Nginx - соответствует только реальным файлам

У меня следующая конфигурация nginx:

server {
    listen 8080;

    root /site_root/web;
    index index.html;

    server_name www.mysite.com;

    location / {
        try_files $uri @rewriteapp;
    }

    location @rewriteapp {
        rewrite ^(.*)$ /app.php/$1 last;
    }

    # add headers to static files
    location ~* \.(?:ico|css|js|gif|jpe?g|png|svg|woff|ttf|eot)$ {
        expires 365d;
        add_header Pragma public;
        add_header Cache-Control "public";
    }

    location ~ \.php {
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS $https;
        fastcgi_pass unix:/var/run/php-fpm-www.sock;
    }
}

Проблема Это стандартное приложение php с фронт-контроллером и некоторыми статическими активами (js / css и т. Д.), Размещенными в виде файлов в файловой системе (в качестве аргументов расположение этих файлов - / site_root / web / assets).

Целью приведенной выше конфигурации является добавление заголовков «max-age» к этим статическим файлам, чтобы браузеры могли их кэшировать. Это работает для всех файлов, существующих в файловой системе. тем не мение У меня есть ресурсы, которые генерируются динамически и должны проходить через php ('/site_root/web/assets/dynamic/file.uk.js', '/site_root/web/assets/dynamic/file.us.js', ' /site_root/web/assets/variable/variable.uk.js ').

Проблема в том, что включение директивы местоположения «добавить заголовки в статические файлы» приводит к тому, что эти динамические файлы становятся 404. Как я могу это сделать (в порядке желательности каждого решения):

Nginx использует только один блок местоположения

Это сводится к тому, что nginx будет использовать только один блок местоположения. Что-нибудь в Другой блоки местоположения игнорируются. В вопросе любой запрос, который соответствует блоку местоположения "статические файлы", независимо от того, существует файл или нет, будет обрабатываться только этим блоком местоположения. Когда возникает какая-то двусмысленность, я нахожу полезный метод отладки:

location /something-else {
    add_header "section" "something else location"; 
    # ^ if this location block is used, that header is in the output
    ...
}

В заголовки ответа будет включен заголовок, добавленный из совпавшего блока:

$ curl -I "http://nginx.h5bp.dev/something"
...
section: something location # <- like so

Решения

Есть много решений, и вы можете найти этот справочный материал полезно читать. Следует иметь в виду, что nginx предназначен для использования с префиксной маршрутизацией, что облегчает жизнь nginx и вам.

Префиксная маршрутизация

Итак, если вы можете это сделать:

location ~ ^/(css|images|js)/ {
    expires 365d;
    add_header Pragma public;
    add_header Cache-Control "public";
}

location ~ \.php {
    ...
}

Это было бы оптимальным решением. При необходимости также можно использовать расширение с использованием вложенных блоков местоположения:

location ~ ^/(css|images|js)/ {
    location ~* \.(?:whatever|ext)$ {
        expires 365d;
        add_header Pragma public;
        add_header Cache-Control "public";
    }
}

location ~ \.php {
    ...
}

Поместите файлы try во все блоки местоположения

В вопросе есть один блок местоположения - так что это очевидная альтернатива, как упомянул Майкл:

location ~* \.(?:ico|css|js|gif|jpe?g|png|svg|woff|ttf|eot)$ {
    try_files $uri @rewriteapp; # <- added
    expires 365d;
    add_header Pragma public;
    add_header Cache-Control "public";
}

location ~ \.php {
    ...
}

Однако, если у вас есть несколько блоков местоположения, это становится довольно утомительным (хотя, вероятно, также указывает на то, что nginx не используется в соответствии с дизайном)

404 Фронтальный контроллер

Настройка будет работать всегда, независимо от того, как выглядят ваши блоки местоположения, заключается в использовании переднего контроллера 404. В вашем случае это будет означать:

server {
    listen 8080;

    root /site_root/web;
    index index.html;

    server_name www.mysite.com;

    try_files $uri $uri/ @rewriteapp;
    error_page 404 = @rewriteapp

    location @rewriteapp {
        rewrite ^ /app.php/$request_uri last;
    }

    # add headers to static files
    location ~* \.(?:ico|css|js|gif|jpe?g|png|svg|woff|ttf|eot)$ {
        expires 365d;
        add_header Pragma public;
        add_header Cache-Control "public";
    }

    location ~ \.php {
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
        fastcgi_param PATH_INFO $fastcgi_path_info;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param HTTPS $https;
        fastcgi_pass unix:/var/run/php-fpm-www.sock;
    }
}

Или похожие. Выберите наиболее простое и удобное решение.

Почему бы вам просто не передать их в ваше приложение?

location ~* \.(?:ico|css|js|gif|jpe?g|png|svg|woff|ttf|eot)$ {
    try_files $uri @rewriteapp;
    #...everything else