如何在Nginx下配置Flutter Web子路径(开发/生产环境)
同一域名下部署多个Flutter Web应用的解决方案(子路径/子域名)
一、子路径部署的核心修复步骤
当前出现的MIME类型错误、Manifest语法错误,本质是静态资源路径解析错误,导致Nginx返回了HTML页面而非对应资源。以下是分步修复方案:
1. 正确构建Flutter Web应用
不要手动修改index.html中的base href,通过构建参数指定子路径:
flutter build web --base-href "/app1/"
该命令会自动将生成的index.html中<base href>设置为/app1/,确保所有静态资源、路由都基于此前缀加载。
2. 调整Nginx配置
修正proxy_pass的路径拼接逻辑,移除不必要的sub_filter:
server { listen 8081; server_name localhost; access_log /opt/homebrew/var/log/nginx/access.log; location /api { proxy_pass http://localhost:4000/api; } location /app1 { proxy_pass http://localhost:3666/; # 末尾的/是关键:将/app1/xxx转发到localhost:3666/xxx proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } # app2配置可参照app1,替换端口和子路径即可 # location /app2 { # proxy_pass http://localhost:xxxx/; # ...(同app1的proxy配置) # } }
关键说明:proxy_pass末尾的/会让Nginx自动剥离/app1前缀,将剩余路径转发到Flutter服务的根目录,确保静态资源能正确匹配。
3. 调整GoRouter路由配置
GoRouter无需添加/app1前缀,因为base href已经处理了路径上下文,保持路由为相对路径即可:
Future<void> main() async { usePathUrlStrategy(); // ...其他初始化逻辑 } GoRouter getRouter(WidgetRef ref) { // ...其他配置 return GoRouter( initialLocation: '/dashboard', // 对应访问路径:localhost:8081/app1/dashboard routes: [ ShellRoute( builder: (context, state, child) { return TvsScaffold(child: child); }, routes: [ GoRoute( name: 'home', path: '/', // 对应访问路径:localhost:8081/app1/ builder: (context, state) => const Dashboard(), ), GoRoute( name: 'dashboard', path: 'dashboard', // 对应访问路径:localhost:8081/app1/dashboard builder: (context, state) => const Dashboard(), ), // 其他子路由保持相对路径配置 ], ), ], ); }
4. 验证修复效果
- 启动Flutter开发服务(
flutter run -d chrome --web-port 3666)或部署构建后的静态文件到3666端口服务 - 重启Nginx
- 访问
localhost:8081/app1,检查浏览器控制台是否还有资源加载错误,静态资源(如flutter_bootstrap.js、manifest.json)应返回正确的MIME类型。
二、子域名部署的CORS问题修复(备选方案)
若后续想换回子域名方案,可通过以下配置解决Cookie跨域问题:
- 统一根域名:所有服务使用同一根域名的子域名,如
api.example.com、app1.example.com、app2.example.com - API服务设置CORS响应头:
若允许所有子域名,可设置Access-Control-Allow-Origin: https://app1.example.com Access-Control-Allow-Credentials: true Access-Control-Allow-Headers: Content-Type, AuthorizationAccess-Control-Allow-Origin: *.example.com - Cookie跨域配置:
设置Cookie的Domain为根域名,SameSite为Lax或None(跨域时需配合Secure):Set-Cookie: auth_token=xxx; Domain=.example.com; Path=/; SameSite=Lax; Secure - Nginx子域名配置:每个子域名单独配置
server块,指向对应服务即可。
三、常见问题排查
- 若仍出现MIME类型错误:直接访问
localhost:3666/flutter_bootstrap.js确认资源存在且返回正确MIME类型,再对比Nginx转发后的请求是否一致。 - Manifest错误:通常是
manifest.json路径错误导致返回HTML,解决静态资源路径问题后自动修复。
内容的提问来源于stack exchange,提问作者Casper Kaandorp
相关产品推荐
相关产品推荐

