Laravel(Statamic)站点Nginx下图片资源域名重复引发404错误求助
问题
使用Nginx部署Laravel(Statamic)站点后,CMS加载本地存储图片时出现404错误。Chrome控制台显示请求URL为staging.site.com/staging.site.com/storage/images/image.png,但HTML中的URL是正确的staging.site.com/storage/images/image.png,疑似Nginx处理时域名重复。
已排查内容
- 已执行
php artisan storage:link创建存储软链接,服务器上图片文件存在; - 手动移除重复域名后可正常访问图片;
- Nginx和Laravel日志无相关错误信息。
补充信息
- 使用Certbot配置SSL;
- 本地开发环境正常,推测是Nginx配置问题;
- 排除UFW防火墙问题,URL正确时可访问文件。
相关配置文件
nginx.conf
user username; worker_processes auto; pid /run/nginx.pid; include /etc/nginx/modules-enabled/*.conf; events { worker_connections 768; } http { sendfile on; tcp_nopush on; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE ssl_prefer_server_ciphers on; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; gzip on; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; client_max_body_size 50M; }
Laravel站点配置(sites-enabled/laravel)
server { # server_name _; server_name staging.site.com; root /var/www/site/public; add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff"; index index.html index.htm index.php; charset utf-8; proxy_busy_buffers_size 512k; proxy_buffers 4 512k; proxy_buffer_size 256k; location / { try_files $uri $uri/ /index.php?$query_string; } location = /favicon.ico { access_log off; log_not_found off; } location = /robots.txt { access_log off; log_not_found off; } error_page 404 /index.php; location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; include fastcgi_params; } location ~ /\.(?!well-known).* { deny all; } listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/staging.site.com/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/staging.site.com/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { if ($host = staging.site.com) { return 301 https://$host$request_uri; } # managed by Certbot server_name staging.site.com; listen 80; return 404; # managed by Certbot }
原因分析与解决方法
核心原因
问题源于Nginx未正确传递关键FastCGI参数,导致Laravel/Statamic生成资源URL时无法识别当前请求的域名和协议,错误地重复拼接域名。具体来说,HTTP_HOST、REQUEST_SCHEME等参数缺失或未正确传递,框架会基于错误的基础URL生成资源路径。
解决步骤
检查并补充FastCGI参数
打开/etc/nginx/fastcgi_params文件,确保包含以下参数:fastcgi_param HTTP_HOST $host; fastcgi_param REQUEST_SCHEME $scheme; fastcgi_param HTTPS $https if_not_empty;若缺失,添加后保存文件。
调整站点配置中的PHP处理块
在PHP请求的location块中,明确添加上述参数(避免被默认配置覆盖),调整后代码如下:location ~ \.php$ { fastcgi_pass unix:/var/run/php/php8.2-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; # 明确传递关键参数 fastcgi_param HTTP_HOST $host; fastcgi_param REQUEST_SCHEME $scheme; fastcgi_param HTTPS $https if_not_empty; include fastcgi_params; }清除Laravel缓存
执行命令清除框架缓存,确保配置生效:php artisan cache:clear php artisan config:clear php artisan view:clear重启服务
重启Nginx和PHP-FPM使配置生效:sudo systemctl restart nginx sudo systemctl restart php8.2-fpm
额外验证点
确认.env文件中APP_URL配置项正确设置为站点域名:
APP_URL=https://staging.site.com
内容的提问来源于stack exchange,提问作者dmcoding
相关产品推荐
相关产品推荐

