Flutter iOS端POST登录请求报错意外字符 安卓运行正常
故障根因
你遇到的FormatException: Unexpected character (at character 1)报错本质是jsonDecode尝试解析的内容不是合法JSON格式,安卓端请求正常iOS失败,主要是两个平台的HTTP请求默认配置、网络环境适配有差异,常见触发原因如下:
- 服务端返回了非JSON格式内容(比如HTML错误页、纯文本报错),iOS端请求不符合服务端要求导致参数解析失败
- iOS端的HTTP请求未显式指定
Content-Type,部分服务端无法识别form格式的请求参数 - 本地测试时接口地址用了127.0.0.1,iOS模拟器无法访问开发机本地服务
- 服务端返回的JSON带了BOM头,iOS端解析时会把BOM头识别为非法字符
修复步骤
1. 先定位实际返回内容
在解析响应前添加调试代码,打印状态码和原始响应内容,确认返回结果:
login(email, password) async { var url = Uri.parse('http://xxxxxxx.com/api/login'); try { var response = await http.post(url, body: {"email": email, "password": password}); // 新增调试代码 print('响应状态码:${response.statusCode}'); print('原始响应内容:${response.body}'); var data = jsonDecode(response.body); // 原有逻辑省略 }}
运行后查看控制台输出,如果返回的是HTML/乱码/纯文本报错,就可以针对性处理。
2. 显式配置请求头
给POST请求显式指定Content-Type,和安卓端默认配置保持一致:
var response = await http.post( url, headers: {'Content-Type': 'application/x-www-form-urlencoded'}, body: {"email": email, "password": password}, );
如果服务端支持JSON格式传参,也可以改为JSON传参适配:
var response = await http.post( url, headers: {'Content-Type': 'application/json'}, body: jsonEncode({"email": email, "password": password}), );
3. 适配本地测试环境
如果你使用的是本地部署的测试服务端,不要用127.0.0.1作为接口地址,替换为你的开发机所在的局域网IP(比如192.168.3.4这类格式),iOS模拟器才能正常访问开发机的服务。
4. 兼容BOM头场景
如果调试发现响应内容开头有不可见的BOM头,解析前先清理BOM头:
String rawBody = response.body; // 移除UTF-8 BOM头 if (rawBody.startsWith('\u{feff}')) { rawBody = rawBody.substring(1); } var data = jsonDecode(rawBody);
5. 添加异常兜底
给JSON解析逻辑添加异常捕获,避免直接崩溃同时可以提示用户:
try { var data = jsonDecode(rawBody); } catch (e) { print('解析失败:$e,响应内容:${response.body}'); // 这里可以添加Toast/弹窗提示用户登录失败 }
内容的提问来源于stack exchange,提问作者Sermed mayi
相关产品推荐
相关产品推荐

