Android模拟器连接Node.js后端时CRUD更新/删除操作失败问题
问题描述
我使用Android模拟器将App连接至运行在3000端口的Node.js后端,服务器地址配置为:
final serverUrl = 'http://10.0.2.2:3000';
App已实现CRUD功能,但每次尝试更新或删除条目时,代码中的异常都会被抛出,且条目未被修改或删除。
前端Dart核心代码
Future<List<Item>> fetchItems() async { final response = await http.get(Uri.parse('$serverUrl/api/v1/items')); if (response.statusCode == 200) { final List<dynamic> itemList = jsonDecode(response.body); final List<Item> items = itemList.map((json) => Item.fromJson(json)).toList(); return items; } else { throw Exception('Failed to fetch items'); } } Future<Item> addItem(String name) async { final response = await http.post(Uri.parse('$serverUrl/api/v1/items'), headers: {'content-type': 'application/json'}, body: jsonEncode({'name': name})); if (response.statusCode == 200) { final dynamic json = jsonDecode(response.body); final Item item = Item.fromJson(json); return item; }else{ throw Exception('Failed to fetch item'); } } Future<void> updateItem(int id, String name) async { final response = await http.delete( Uri.parse('$serverUrl/api/v1/items/$id'), headers: {'Content-Type': 'application/json'}, body: jsonEncode({"name": name}), ); if (response.statusCode != 200) { throw Exception('Failed to update item'); } } Future<void> deleteItem(int id) async { final response = await http.delete(Uri.parse('$serverUrl/api/v1/items/$id')); if (response.statusCode != 200) { throw Exception('Failed to delete item'); } }
UI触发代码
IconButton( icon: const Icon(Icons.edit), onPressed: () { dialog('Edit item', 'Edit', onPressed: () { updateItem(item.id, nameController.text); Navigator.pop(context); }); }, ), floatingActionButton: FloatingActionButton( onPressed: () { dialog('Add item', 'Item name', onPressed: () { addItem(nameController.text); Navigator.pop(context); }); }, tooltip: 'Add button', child: const Icon(Icons.add), )
后端Node.js接口代码
const express = require('express'); const app = express(); const port = process.env.port || 3000; const itemList = [ {id: 1, name: 'name here'}, ]; app.put('/api/v1/items/:id', (req, res) => { let itemId = req.params.id; let updatedItem = { id: itemId, name: req.body.name } const index = itemList.findIndex(item => item.id === itemId); if(index !== -1){ itemList[index] = updatedItem res.json(updatedItem); }else{ res.status(404).json({message: 'Item not found'}) } }) app.delete('/api/v1/items/:id', (req, res) => { let itemId = req.params.id; let index = itemList.findIndex(item => item.id === itemId); if(index!== -1){ let deletedItem = itemList.splice(index, 1); res.json(deletedItem[0]) }else{ res.status(404).json({message: 'Item not found'}) } })
问题原因及修复方案
1. 请求方法不匹配
前端updateItem方法错误使用了http.delete请求,但后端更新接口定义的是PUT方法,导致请求无法被正确处理。
修复:将updateItem中的请求方法改为http.put:
Future<void> updateItem(int id, String name) async { final response = await http.put( Uri.parse('$serverUrl/api/v1/items/$id'), headers: {'Content-Type': 'application/json'}, body: jsonEncode({"name": name}), ); if (response.statusCode != 200) { throw Exception('Failed to update item'); } }
2. ID类型不匹配
后端从req.params.id获取的是字符串类型,而前端传入的是整数类型,使用===严格相等比较会导致找不到对应条目。
修复:后端将参数ID转为数字类型:
// 更新接口 let itemId = Number(req.params.id); // 删除接口 let itemId = Number(req.params.id);
3. 后端未解析JSON请求体
后端缺少express.json()中间件,无法解析前端POST/PUT请求的JSON格式请求体,导致req.body.name为undefined。
修复:在定义接口前添加中间件:
app.use(express.json());
4. (可选)捕获异步操作异常
UI触发更新/删除时,建议添加异常捕获逻辑,避免App崩溃:
IconButton( icon: const Icon(Icons.edit), onPressed: () { dialog('Edit item', 'Edit', onPressed: () async { try { await updateItem(item.id, nameController.text); // 可在此处刷新列表 } catch (e) { print(e); // 或提示用户操作失败 } Navigator.pop(context); }); }, ),
内容的提问来源于stack exchange,提问作者Achievers Tv
相关产品推荐
相关产品推荐

