无法到达 POST 请求缓存的嵌套位置指令

Unable to reach nested location directive for POST request caching

我正在配置 NginX 以支持缓存 GET 请求 + 特定的 POST 请求。 我正在使用 symfony 框架,因此将 URI 重写为:app.php/... .

为了能够分开处理 GET 和 POST 缓存,我创建了一些嵌套的位置指令。

fastcgi_cache_path /nginx_cache_path levels=1:2 keys_zone=one:10m max_size=1g inactive=120m loader_threshold=300 loader_files=150;

server {
    listen 80;
    server_name example.com www.example.com;

    if ($request_method !~ ^(GET|HEAD|POST)$ ) {
        return 444;
    }

    root /path_to_web_server;

    location / {            

        # try to serve file directly. If not existing change to app.php
        try_files $uri /app.php$is_args$args;          

    }

    location ~ ^/images/.*\.(gif|jpg|png)$ {

        root /path_to_images_folder;
    }

    location ~ ^/app\.php(/|$) {

        location ~ /post_request_path {

            fastcgi_cache_key "$request_uri|$request_body";
            fastcgi_cache_valid 5m;           
            fastcgi_cache_methods POST;

            fastcgi_cache one;
            fastcgi_cache_use_stale updating error timeout invalid_header http_500 http_503 http_404;

            fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
            add_header X-Fastcgi-Cache $upstream_cache_status;
            fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;
            include fastcgi_params;

            fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
            fastcgi_param DOCUMENT_ROOT $realpath_root;

            internal;
        }

        location ~ / {

            fastcgi_cache_key $scheme$host$request_uri$request_method;
            fastcgi_cache_valid 60m;          
            fastcgi_cache_methods GET HEAD;

            fastcgi_cache one;
            fastcgi_cache_use_stale updating error timeout invalid_header http_500 http_503 http_404;

            fastcgi_ignore_headers Cache-Control Expires Set-Cookie;
            add_header X-Fastcgi-Cache $upstream_cache_status;
            fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
            fastcgi_split_path_info ^(.+\.php)(/.*)$;
            include fastcgi_params;

            fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
            fastcgi_param DOCUMENT_ROOT $realpath_root;

            internal;
        }
}

我的问题:POST 请求从未被缓存。 "location ~ /post_request_path" 经过测试但从未被 NginX 选择。

根据 NginX 调试日志文件:

2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: "/"
2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: ~ "^/images/.*\.(gif|jpg|png)$"
2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: ~ "^/app\.php(/|$)"
2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: ~ "\.php$"
2017/07/11 19:31:00 [debug] 13707#0: *8961 using configuration "/"
2017/07/11 19:31:00 [debug] 13707#0: *8961 internal redirect: "/app.php?"
2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: "/"
2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: ~ "^/images/.*\.(gif|jpg|png)$"
2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: ~ "^/app\.php(/|$)"
2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: ~ "/post_request_path"
2017/07/11 19:31:00 [debug] 13707#0: *8961 test location: ~ "/"
2017/07/11 19:31:00 [debug] 13707#0: *8961 using configuration "/"

我很惊讶 /post_request_path 从未被选中,因为我认为 NginX 算法在多个正则表达式匹配 URI 时选择了第一个匹配的正则表达式。

我想我在这里遗漏了一些嵌套位置指令的重要内容...

有线索吗?

我自己找到了解决方案。我在错误的方向上挖掘。问题不是来自嵌套位置指令,而是来自 try_files 指令。

调试日志中原因在我眼皮底下:

2017/07/11 19:31:00 [debug] 13707#0: *8961 internal redirect: "/app.php?"

NginX 正在将 URI 重写为“/app.php?”而不是“/app.php/post_request_path”

因此 "wrong" 位置指令路线。

更正

变化:

try_files $uri /app.php$is_args$args;

try_files $uri /app.php$uri;