You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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. 验证修复效果

  1. 启动Flutter开发服务(flutter run -d chrome --web-port 3666)或部署构建后的静态文件到3666端口服务
  2. 重启Nginx
  3. 访问localhost:8081/app1,检查浏览器控制台是否还有资源加载错误,静态资源(如flutter_bootstrap.js、manifest.json)应返回正确的MIME类型。

二、子域名部署的CORS问题修复(备选方案)

若后续想换回子域名方案,可通过以下配置解决Cookie跨域问题:

  1. 统一根域名:所有服务使用同一根域名的子域名,如api.example.com、app1.example.com、app2.example.com
  2. API服务设置CORS响应头:
    Access-Control-Allow-Origin: https://app1.example.com
    Access-Control-Allow-Credentials: true
    Access-Control-Allow-Headers: Content-Type, Authorization
    
    若允许所有子域名,可设置Access-Control-Allow-Origin: *.example.com
  3. Cookie跨域配置:
    设置Cookie的Domain为根域名,SameSite为Lax或None(跨域时需配合Secure):
    Set-Cookie: auth_token=xxx; Domain=.example.com; Path=/; SameSite=Lax; Secure
    
  4. Nginx子域名配置:每个子域名单独配置server块,指向对应服务即可。

三、常见问题排查

  • 若仍出现MIME类型错误:直接访问localhost:3666/flutter_bootstrap.js确认资源存在且返回正确MIME类型,再对比Nginx转发后的请求是否一致。
  • Manifest错误:通常是manifest.json路径错误导致返回HTML,解决静态资源路径问题后自动修复。

内容的提问来源于stack exchange,提问作者Casper Kaandorp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 04:26:06