Linux Nginx子目录托管多个.NET Core7应用静态资源加载失败
解决.NET Core 7子目录托管下静态文件404问题
问题根源
- Nginx反向代理配置冗余:反向代理的
location块中无需root指令,因为请求是转发到本地.NET应用处理,Nginx不需要直接指定静态文件根目录,多余的root会干扰路径解析。 - .NET中间件顺序错误:
UsePathBase必须在UseStaticFiles之前执行,否则路径基配置不会生效。 - 资源URL生成错误:应用默认从根路径加载资源(如
/css/style.css),未带上子目录前缀(如/auth/css/style.css),导致浏览器请求错误路径。
修复步骤
1. 修正Nginx服务器块配置
移除反向代理location中的root指令,修改后的完整配置如下:
server { server_name subdomain.domain.co.za www.subdomain.domain.co.za; error_log /var/apps/domain.co.za/logs/domain.log; root /var/www/subdomain.domain.co.za; location /proxy/ { proxy_pass http://localhost:8886/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /auth/ { proxy_pass http://localhost:8888/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location /api/ { proxy_pass http://localhost:8887/; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection keep-alive; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } location / { root /var/www/subdomain.domain.co.za; index index.html; } listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/subdomain.domain.co.za/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/subdomain.domain.co.za/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 = www.subdomain.domain.co.za) { return 301 https://$host$request_uri; } # managed by Certbot if ($host = subdomain.domain.co.za) { return 301 https://$host$request_uri; } # managed by Certbot server_name subdomain.domain.co.za www.subdomain.domain.co.za; listen 80; return 404; # managed by Certbot }
2. 调整.NET Core应用的中间件配置
针对auth应用,先启用转发头处理,再设置路径基,最后配置静态文件,确保中间件顺序正确:
// 启用转发头处理,让应用识别反向代理传递的路径信息 app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); // 设置路径基,必须在UseStaticFiles之前调用 app.UsePathBase("/auth"); // 配置静态文件,RequestPath对应路径基,FileProvider指向应用自身的wwwroot目录 app.UseStaticFiles(new StaticFileOptions { RequestPath = "/auth", FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "wwwroot")) }); // 后续路由、授权等中间件 app.UseRouting(); // ... 其他业务中间件配置
3. 修正视图中的资源路径写法
在Razor视图或HTML文件中,不要使用绝对根路径加载资源,改用.NET辅助方法自动添加子目录前缀:
<!-- 错误写法:绝对根路径 --> <link rel="stylesheet" href="/css/site.css"> <!-- 正确写法1:使用Url.Content辅助方法 --> <link rel="stylesheet" href="@Url.Content("~/css/site.css")"> <!-- 正确写法2:使用Tag Helper --> <link rel="stylesheet" asp-src="~/css/site.css">
4. 重启服务验证
- 重启Nginx:
sudo systemctl restart nginx - 重启对应.NET Core应用(根据你的服务名调整):
sudo systemctl restart auth-app.service - 打开浏览器开发者工具,检查资源请求路径是否已带上
/auth前缀,确认返回200状态码。
内容的提问来源于stack exchange,提问作者Okuhle
相关产品推荐
相关产品推荐

