我有一个包含以下块的虚拟主机location
:
server {
listen 80;
server_name ~^(?<username>[^.]+)\.project*/\.client\.com$;
root /home/$username/project/app/webroot;
index index.php;
access_log /var/log/nginx/project.sandbox.access.log;
error_log /var/log/nginx/project.sandbox.error.log;
location / {
try_files $uri $uri/ /index.php?url=$uri;
}
location ~ \.php$ {
include /etc/nginx/includes/php;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
include /etc/nginx/includes/ignore;
}
我以前从未遇到过问题,但我刚刚添加了一项允许用户上传和存储文件的功能。如果用户上传 pdf、txt 文件等,一切正常,我可以通过其 URL 顺利加载上传内容。另一方面,图像就没那么好了。到处都是 404。
我已将范围缩小到这个块,但我不明白。其他图像资源加载正常。唯一的区别(可能造成所有区别)是,上传的资源未加载到块指令定义的 webroot 中server
。root
上传存储在 中/opt/www/app/plugins/...
。有什么原因应该引起注意吗?我的前端控制器处理上传资源的路由。
我想缓存/使内容过期,但我需要先修复 404 问题。
答案1
您的.(js|css|png|jpg|jpeg|gif|ico)
location 块会捕获以这些文件扩展名结尾的已上传资产的请求。由于 nginx 在每个级别仅执行一个 location 块,因此不会针对这些请求执行您的 PHP 脚本。nginx 尝试直接从磁盘提供文件,但找不到已上传的资产。
您需要使此位置块匹配更加严格,以使其不匹配已上传的资产。例如:
location ~* ^/static/.*\.(js|css|png|jpg|jpeg|gif|ico)$
编辑:当我说“级别”时,我指的是嵌套级别。例如:
location / {
location /foo {}
}
location /bar {}
location /baz {
location /baz/quaz {}
location ~ \.php$ {}
}
、/
和location 块位于第 1 级。 、和location/bar
块位于第 2 级,因为它们嵌套在第 1 级 location 块中。假设请求是。nginx 将选择最具体的第 1 级 location 块,在本例中为。不会处理其他第 1 级 location 块,因此块对此请求不起作用。如果有第 2 级 location 块,它将执行相同操作,在本例中将选择并忽略。/baz
/foo
/baz/quaz
\.php$
/baz/quaz/index.php
/baz
/
\.php$
/baz/quaz