![每个位置块的 Nginx client_max_body_size(使用 php frontcontroller 模式)](https://linux22.com/image/622199/%E6%AF%8F%E4%B8%AA%E4%BD%8D%E7%BD%AE%E5%9D%97%E7%9A%84%20Nginx%20client_max_body_size%EF%BC%88%E4%BD%BF%E7%94%A8%20php%20frontcontroller%20%E6%A8%A1%E5%BC%8F%EF%BC%89.png)
我正在寻找解决方案这个问题。我理解为什么该问题中的设置不起作用的原因,但我尝试找到一个可以使其起作用的解决方案。
这个想法是只允许在某些 URL 上上传大文件。我可以使用一个location
块来实现这一点,但问题是:我有一个 php 前端控制器模式:
location ~ \.php {
# ...
fastcgi_pass unix:/tmp/php5-fpm.sock;
}
我的整体配置如下:
# ...
http {
# ...
client_max_body_size 512K;
server {
server_name example.com;
root /var/www/example.com/public;
location / {
try_files $uri /index.php?$query_string;
}
location /admin/upload {
client_max_body_size 256M;
}
location ~ \.php {
# ...
fastcgi_pass unix:/tmp/php5-fpm.sock;
}
}
}
据我了解,只会应用一个位置块。因此,如果我的默认请求大小为 512K,则永远不会应用 256M,因为所有请求都通过 frontcontroller 模式进行匹配~ \.php
。
在这种情况下我是对的吗?如果是这样,那么如何配置才能使得访问者除了上传到之外不能上传任何内容admin/upload
?
答案1
如果/admin/upload
路径是虚拟的,则可以使其按如下方式工作:
location / {
try_files $uri /index.php?$args;
}
location /admin/upload {
client_max_body_size 256M;
include inc/php.conf;
rewrite ^(.*)$ /index.php?$args break;
}
location ~ \.php$ {
include inc/php.conf;
}
虽然不是最漂亮的,但是还是有用。
答案2
定义两个 php 位置?
location ~ ^/admin/upload/.+\.php$
{
client_max_body_size 256M;
include /etc/nginx/conf.d/php-fpm.conf;
}
location ~ \.php
{
include /etc/nginx/conf.d/php-fpm.conf;
}
也许不是最漂亮的...但应该是实用的......
答案3
可以使用多个位置,但有点棘手。
如果您按照上述说明使用try_files
或rewrite
,那么将client_max_body_size
被设置为client_max_body_size
更高上下文的,而不是您真正期望的位置块的。
将您的 PHP FastCGI 配置移动到您可以包含的文件中,例如php-conf.conf
。
然后使用这样的配置:
location / {
# try to serve file directly, fallback to index.php
try_files $uri /index.php$query_string;
}
location ~ ^/admin/upload$ {
client_max_body_size 4m;
include /etc/nginx/php-conf.conf;
fastcgi_param SCRIPT_FILENAME $realpath_root/index.php;
}
location ~ ^/index\.php(/|$) {
include /etc/nginx/php-conf.conf;
internal;
}
请注意,如果您设置了不同的脚本名称,则需要覆盖SCRIPT_FILENAME
才能使用index.php
。这可能是因为fastcgi_split_path_info ^(.+\.php)(/.*)$;
。