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
相关产品推荐
相关产品推荐

