我正在配置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时选择了第一个匹配的正则表达式。
我想我在这里错过了一些关于嵌套位置指令的东西...
有任何线索吗?
答案 0 :(得分:0)
我自己找到了解决方案。我正朝着错误的方向挖掘。问题不是来自嵌套的位置指令,而是来自 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”
因而是“错误的”位置指令路线。
<强>校正强>
变化:
try_files $ uri /app.php$is_args$args;
到
try_files $ uri /app.php$uri;