Flutter实现数据库登录功能时新版代码报FormatException问题求解
问题根本原因
该问题属于Flutter http 包版本升级带来的API使用不匹配问题,具体触发逻辑如下:
- 旧版本
http包的post方法支持直接传入字符串格式的URL作为入参,会在内部自动完成字符串到Uri对象的转换,因此原代码可以正常运行。 - 新版本
http包(1.0.0及以上)废弃了直接传入字符串URL的方法重载,要求入参必须传入合法的Uri类型实例。 - 新代码中错用了
Uri.http构造方法的参数规则:Uri.http和Uri.https的第一个入参仅接收不带协议头的主机地址(Host:Port 格式),直接把带https://前缀的完整URL字符串传入该参数时,构造方法会尝试从字符串中解析端口号(要求为10进制整数),实际拿到的待解析内容为//charlotapp.000webhostapp.com/login.php,无法转换为合法整数,因此触发FormatException: Invalid radix-10 number的报错。 - 额外的参数错配:请求目标是HTTPS协议地址,本身不应该使用面向HTTP协议的
Uri.http构造方法。
代码调整方案
根据上述原因,可选择两种兼容的实现方式完成请求:
方案1:最低改动成本的兼容写法
直接通过Uri.parse()将原有的完整URL字符串转换为合法Uri对象,完全适配旧代码的逻辑,避免拆分参数的错误:
class _Login extends State<Login> { TextEditingController user = TextEditingController(); TextEditingController pass = TextEditingController(); Future login() async { // 用Uri.parse转换完整URL字符串 var url = Uri.parse("https://charlotapp.000webhostapp.com/login.php"); var response = await http.post( url, body: { "username": user.text, "password": pass.text, }); var data = json.decode(response.body); } }
方案2:结构化Uri构建写法
如果需要按结构拆分URL组件构建请求,需要使用对应HTTPS协议的Uri.https构造方法,按规则拆分参数,不能传入带协议头的完整URL:
class _Login extends State<Login> { TextEditingController user = TextEditingController(); TextEditingController pass = TextEditingController(); Future login() async { // 第一个参数为不带协议的主机地址,第二个参数为接口路径 var url = Uri.https("charlotapp.000webhostapp.com", "/login.php"); var response = await http.post( url, body: { "username": user.text, "password": pass.text, }); var data = json.decode(response.body); } }
额外检查项
- 完成Uri解析问题修复后,需确认Android端已开启对应网络访问权限、iOS端已配置对应域名的ATS例外规则,否则会触发后续的网络访问拦截报错。
- 可通过打印
url.toString()的方式校验最终生成的Uri是否和预期URL完全一致,提前排查参数拆分错误。
内容的提问来源于stack exchange,提问作者jojoji54
相关产品推荐
相关产品推荐

