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

Flutter对接Node.js API本地正常,线上遇连接及SSL错误求助

问题排查与解决方案

错误1:ERR_CONNECTION_REFUSED(使用localhost请求时)

原因

Flutter Web部署到服务器后,运行在用户的浏览器环境中,此时localhost指向的是用户本地设备,而非Node.js API所在的服务器,因此无法建立连接。

解决方案

  • 禁止硬编码localhost作为API地址,替换为API所在服务器的公网IP或域名,同时确保该地址可被外部访问。
  • 推荐通过环境变量动态配置API地址,区分开发/生产环境:
    // 构建时通过命令传入生产环境API地址:flutter build web --dart-define=API_URL=https://your-api-domain.com
    final apiBaseUrl = const String.fromEnvironment(
      'API_URL',
      defaultValue: 'http://localhost:3000' // 开发环境默认值
    );
    
    void _fetchItemDescription(String cpsNumber) async {
      final url = Uri.parse('$apiBaseUrl/surplusItems?CPSNumber=$cpsNumber');
      // ... 原有请求逻辑
    }
    

错误2:ERR_SSL_PROTOCOL_ERROR(使用服务器IP时)

原因

  1. 混合内容限制:若Flutter Web部署在HTTPS服务器上,浏览器会阻止页面加载HTTP协议的API资源(安全策略禁止HTTPS页面加载非HTTPS内容)。
  2. API未配置SSL:当前Node.js API仅通过HTTP运行,无SSL证书,浏览器尝试用HTTPS访问HTTP端口时会触发SSL协议错误。

解决方案

方案1:给Node.js API配置HTTPS(直接生效)

为API添加SSL证书(可使用Let's Encrypt免费证书),让API通过HTTPS提供服务:

const https = require('https');
const fs = require('fs');
const express = require('express');

const app = express();
// ... 保留原有的中间件、路由逻辑

// 替换为你的SSL证书路径
const sslOptions = {
  key: fs.readFileSync('/etc/letsencrypt/live/your-domain.com/privkey.pem'),
  cert: fs.readFileSync('/etc/letsencrypt/live/your-domain.com/fullchain.pem')
};

// 启动HTTPS服务器
https.createServer(sslOptions, app).listen(3000, () => {
  console.log(`HTTPS Server running on port 3000`);
});

修改Flutter中的API地址为HTTPS:

final url = Uri.parse('https://your-server-ip:3000/surplusItems?CPSNumber=$cpsNumber');

方案2:使用Nginx反向代理(生产环境推荐)

通过Nginx托管Flutter Web静态文件,并将API请求转发到Node.js服务,彻底避免混合内容问题:

server {
    listen 443 ssl;
    server_name your-domain.com;

    # SSL证书配置
    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;

    # 托管Flutter Web静态文件
    location / {
        root /var/www/flutter-web-build; # 替换为你的Flutter构建文件路径
        try_files $uri $uri/ /index.html;
    }

    # 转发API请求到Node.js
    location /surplusItems {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }

    location /submitSurplusItems {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

此时Flutter可使用相对路径请求API,无需硬编码域名:

final url = Uri.parse('/surplusItems?CPSNumber=$cpsNumber');

额外检查项

  1. 端口开放:确保服务器防火墙已开放对应端口(HTTPS用443,直接访问API用3000)。
  2. API可访问性:先用curl或浏览器测试API地址是否正常返回数据:
    curl https://your-domain.com/surplusItems?CPSNumber=test
    
  3. CORS安全优化:生产环境建议限制CORS允许的域名,避免origin: '*'的宽松配置:
    app.use(cors({ origin: 'https://your-flutter-web-domain.com' }));
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 17:59:50