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

如何在Flutter应用中通过Dio解析容器IP解决API调用失败问题

问题根源

浏览器运行在宿主机网络环境,而非Docker容器的内部网络,所以无法识别docker-compose中定义的backend服务名——只有Docker内部网络里的容器才能通过服务名互相访问,这就是为什么你在Flutter容器里用curl能通,但浏览器调用报错的原因。

解决方案

方案1:直接使用宿主机IP/localhost(本地开发首选)

把代码里的API地址替换成宿主机的IP或者localhost(本地开发时用),因为你已经在docker-compose里把后端的8888端口映射到了宿主机:

void fetchData() async {
    try {
      setState(() {
        isLoading = true;
      });
      // 替换为localhost或你的宿主机实际IP
      var response = await dio.get(
        "http://localhost:8888/api/screen",
      );
      if (response.statusCode == 200) {
        setState(() {
          lineData = jsonDecode(response.data);
          isLoading = false;
        });
      }
    } on DioError catch (err) {
      print(err);
      isLoading = false;
    } catch (_) {
      setState(() {
        isLoading = false;
      });
    }
  }

方案2:配置反向代理(生产环境推荐)

用Nginx做反向代理,把前端和后端的请求统一由Nginx转发,前端请求用相对路径,避免硬编码IP。修改docker-compose.yml新增Nginx服务:

version: '3'
services:
  playground-web-frontend:
    build:
      context: ./flutterapp
      dockerfile: frontend.dockerfile
    # 不再直接映射端口,由Nginx转发
  backend:
    image: backend
  nginx:
    image: nginx:alpine
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    ports:
      - 4040:80

然后创建nginx.conf配置文件:

events {}
http {
    server {
        listen 80;

        # 前端请求转发
        location / {
            proxy_pass http://playground-web-frontend:4040;
        }

        # API请求转发到后端
        location /api/ {
            proxy_pass http://backend:8888/api/;
        }
    }
}

最后修改Flutter代码里的API地址为相对路径:

var response = await dio.get("/api/screen");

方案3:修改宿主机hosts文件(仅本地临时测试用)

在宿主机的hosts文件中添加一行:

127.0.0.1 backend

这样浏览器会把backend解析到本地,但这个方法只适合本地开发测试,线上环境不适用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:20:28