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

Flutter调用Node.js API遇Connection refused错误求助

Flutter调用本地Node.js API出现连接拒绝错误排查

我在开发Flutter应用时遇到连接拒绝错误,具体报错信息如下:

Exception has occurred.
_ClientSocketException (ClientException with SocketException: Connection refused (OS Error: Connection refused, errno = 111), address = localhost, port = 56810, uri=http://localhost:3000/api/v1/products?token=)

我的相关代码如下:

Products模型代码(models/products.dart)

class Products {
  final String? id;
  final String? createdAt;
  final String? price;
  final String? name;
  final String? description;
  final String? color;
  final String? stock;
  final List<dynamic>? ordersList;

  const Products(
      {this.id,
      this.createdAt,
      this.price,
      this.name,
      this.description,
      this.color,
      this.stock,
      this.ordersList});

  Map<String, Object?> toJson() {
    return {
      'id': id,
      'createdAt': createdAt,
      'price': price,
      'name': name,
      'description': description,
      'color': color,
      'stock': stock,
      'ordersList': ordersList
    };
  }

  static Products fromJson(Map<String, Object?> json) {
    return Products(
      id: json['id'] == null ? null : json['id'] as String,
      createdAt: json['createdAt'] == null ? null : json['createdAt'] as String,
      price: json['price'] == null ? null : json['price'] as String,
      name: json['name'] == null ? null : json['name'] as String,
      description:
          json['description'] == null ? null : json['description'] as String,
      color: json['color'] == null ? null : json['color'] as String,
      stock: json['stock'] == null ? null : json['stock'] as String,
      ordersList: json['ordersList'] == null
          ? null
          : json['ordersList'] as List<dynamic>
    );
  }
}

API请求控制器代码(productsController.dart)

import 'dart:convert';
import 'package:front_paye_ton_kawa/config/constants/ipadress.dart';
import 'package:front_paye_ton_kawa/models/products.dart';
import 'package:http/http.dart' as http;

class ProductsController {
  Future<List<Products>> getAllProducts(final String token) async {
    String urlString = "http://localhost:3000/api/v1/products?token=$token";
    final response = await http.get(Uri.parse(urlString));
    if (response.statusCode == 200) {
      // 请求成功
      var products = <Products>[];
      for (var product in json.decode(response.body)) {
        products.add(Products.fromJson(product));
      }
      return products;
    } else {
      // 请求失败
      throw Exception(
          "请求失败,错误代码: ${response.statusCode}");
    }
  }

  Future<Products> getProductsById(
      final String idProduct, final String token) async {
    String urlString =
        "http://localhost:3000/api/v1/products/$idProduct?token=$token";
    final response = await http.get(Uri.parse(urlString));
    if (response.statusCode == 200) {
      // 请求成功
      var product = json.decode(response.body);
      var products = Products.fromJson(product);
      return products;
    } else {
      // 请求失败
      throw Exception(
          "请求失败,错误代码: ${response.statusCode}");
    }
  }
}

Node.js服务端代码

我通过以下命令初始化并安装依赖:

npm init -y
npm install express

服务端代码:

const express = require('express');
const app = express();
const PORT = process.env.PORT || 3000;

const products = [
  {
    id: '1',
    createdAt: '2023-08-24',
    price: '199.99',
    name: 'Krups Coffee Machine',
    description: 'High-quality coffee machine by Krups.',
    color: 'Black',
    stock: '10',
    ordersList: [],
  },
  {
    id: '2',
    createdAt: '2023-08-24',
    price: '149.99',
    name: 'Philips Coffee Machine',
    description: 'Elegant coffee machine by Philips.',
    color: 'Silver',
    stock: '15',
    ordersList: [],
  },
  {
    id: '3',
    createdAt: '2023-08-24',
    price: '129.99',
    name: 'Senseo Coffee Machine',
    description: 'Compact coffee machine by Senseo.',
    color: 'Red',
    stock: '5',
    ordersList: [],
  },
];

app.get('/api/v1/products', (req, res) => {
  res.json(products);
});

app.get('/api/v1/products/:id', (req, res) => {
  const productId = req.params.id;
  const product = products.find(p => p.id === productId);
  if (product) {
    res.json(product);
  } else {
    res.status(404).json({ message: 'Product not found' });
  }
});

app.listen(PORT, () => {
  console.log(`Server is running on port ${PORT}`);
});

运行node index.js后,服务端显示“Server is running on port 3000”,但Flutter调用API时仍出现连接拒绝错误,请求排查原因。


问题排查及解决方法

1. 替换localhost为实际IP地址

Flutter模拟器/真机中的localhost指向设备自身,而非开发机器。需将请求URL中的localhost替换为开发机器的局域网IP:

  • 查看开发机器局域网IP:Windows用ipconfig,Mac/Linux用ifconfig或ip a
  • 修改productsController.dart中的URL:
    String urlString = "http://你的局域网IP:3000/api/v1/products?token=$token";
    

2. 调整Node.js服务监听范围

默认app.listen(PORT)仅监听本地回环地址,导致外部设备无法访问。修改服务端监听代码,让服务监听所有网络接口:

app.listen(PORT, '0.0.0.0', () => {
  console.log(`Server is running on port ${PORT}`);
});

3. 检查防火墙设置

确保开发机器的防火墙允许3000端口的入站连接,避免拦截Flutter的请求。

4. 验证API可访问性

  • 在开发机器浏览器中访问http://localhost:3000/api/v1/products,确认返回正确JSON数据
  • 用局域网IP访问(如http://192.168.1.100:3000/api/v1/products),确保局域网内可正常访问

5. 配置应用网络权限

  • Android:在AndroidManifest.xml中添加网络权限
    <uses-permission android:name="android.permission.INTERNET" />
    
  • iOS:在Info.plist中添加HTTP请求允许配置
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSAllowsArbitraryLoads</key>
        <true/>
    </dict>
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 12:37:05