Laravel 11 + Livewire3 开发的项目,有一个基于 Livewire3 的图片上传及预览功能,在本地环境一切正常,上传到服务器后,预览功能提示:图片无法正常显示。
通过浏览器 console 控制台查看图片预览链接为:
https://www.02405.com/livewire/preview-file/EAEcrXh9mE0Dg8OiW8Z1UuRA35ugMa-metabHlmLmpwZw==-.jpg?expires=1749106799&signature=9502ad6d86d0536ec1cc4f322f2962255c597687f0cede294139fa946d8616de
返回的是 401 Unauthorized,再深入的检查一下服务端日志,实际上是 404 Not Found 错误。
问题出现在服务器环境是宝塔配置的 nginx ,在 nginx 配置文件中有如下内容:
location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
error_log /dev/null;
access_log /dev/null;
}
这个规则匹配了 Livewire 的预览 URL!
导致预览 URL 被 Nginx 的静态文件规则拦截了,直接当作静态文件处理,根本没有传递给 PHP 处理!
方案A:修改 Nginx 配置(推荐)
修改您的静态文件处理规则,排除 Livewire 路径:
# 修改现有的图片文件处理规则
location ~ ^(?!/livewire/).*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
error_log /dev/null;
access_log /dev/null;
}
# 在静态文件规则之前添加 Livewire 专用规则
location ~ ^/livewire/ {
try_files $uri /index.php$is_args$args;
}
location ~ .*\.(js|css)?$
{
expires 12h;
error_log /dev/null;
access_log /dev/null;
}
方案B:更精确的静态文件匹配
# 只匹配真正存在的静态文件
location ~ ^/(?:storage|images|assets|uploads)/.*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
error_log /dev/null;
access_log /dev/null;
}
# 或者排除动态路径
location ~ ^(?!/livewire/|!/api/|!/admin/).*\.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
error_log /dev/null;
access_log /dev/null;
}
方案C:完整的修复配置
这是一个完整的、经过优化的 Nginx 配置片段:
server
{
# ... 您现有的 SSL 和基础配置 ...
# Laravel/Livewire 动态路由 - 在静态文件规则之前
location ~ ^/(livewire|api|admin)/ {
try_files $uri /index.php$is_args$args;
}
# 真实存在的静态图片文件
location ~ ^/(storage|images|assets|public)/.*\.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 30d;
error_log /dev/null;
access_log /dev/null;
try_files $uri =404;
}
# 其他静态图片文件(排除动态路径)
location ~ ^(?!/(livewire|api|admin)/).*\.(gif|jpg|jpeg|png|bmp|swf)$ {
expires 30d;
error_log /dev/null;
access_log /dev/null;
try_files $uri /index.php$is_args$args;
}
# CSS/JS 文件
location ~ .*\.(js|css)$ {
expires 12h;
error_log /dev/null;
access_log /dev/null;
try_files $uri /index.php$is_args$args;
}
# ... 您现有的其他配置 ...
}
实测应用方案A后,问题解决,生产环境图片预览正常。