Flutter获取PHP REST API数据抛出异常、IP被封且图片加载失败
问题解决方案
一、IP封禁问题解决(根因处理)
出现IP直接被封禁、连接被服务端主动重置(就是报错里的Connection reset by peer),都是服务端的拦截规则触发导致的,按以下顺序排查修复:
- 检查服务端防火墙/WAF/CDN的限流规则:
不管是用了Nginx的limit_req模块、第三方防护服务、还是服务商自带的防火墙,先把当前被封禁的IP移出黑名单,再调整请求频率阈值,API接口可以设为单IP每分钟最高60次请求,图片等静态资源阈值要单独调高到单IP每分钟200次以上,避免批量加载图片时触发限流。 - 排查自定义拦截逻辑的bug:
如果你自己在PHP代码里实现了IP计数封禁的逻辑,检查计数规则是否正确,比如是否把单页的多次图片请求重复计数、是否有误把正常访问判定为攻击的逻辑,同时清理MySQL里存储的错误封禁IP记录。 - 优化前端请求的标识和并发逻辑:
- Flutter端的默认请求UA很容易被防护规则判定为爬虫,给所有http请求(包括接口、图片请求)加上正常浏览器UA,示例:
// 接口请求加请求头 final response = await http.get(url, headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" });- 给GridView加懒加载配置,只渲染可视区域的单元格,避免一次性发起几十上百个图片并发请求,大幅降低请求量。
二、图片加载异常修复
IP封禁问题解决后,图片加载的SocketException会同步消失,可以再加两个兜底优化避免偶发报错:
- 给图片加载组件加失败兜底,修改gridcell.dart里的FadeInImage配置:
FadeInImage.assetNetwork( placeholder: "images/no_image.png", image: album.thumbnailUrl, width: 100, height: 100, // 加载失败直接显示占位图,不抛出异常 imageErrorBuilder: (context, error, stackTrace) { return Image.asset("images/no_image.png", width: 100, height: 100); }, )
- 给所有网络请求加超时时间,避免无意义的连接挂起,修改Services.dart里的接口请求逻辑:
final response = await http.get(url, headers: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36" }).timeout(const Duration(seconds: 10));
内容的提问来源于stack exchange,提问作者Heet Kalaria
相关产品推荐
相关产品推荐

