文章目录
- 前言
- [一、iOS ATS 机制概述](#一、iOS ATS 机制概述)
- 二、配置操作步骤与方案详解
-
- [1、方案一 : 指定域名例外 ( 生产环境推荐 , 可正常上架 )](#1、方案一 : 指定域名例外 ( 生产环境推荐 , 可正常上架 ))
-
- 操作步骤
- [Xcode 可视化操作对应项](#Xcode 可视化操作对应项)
- [2、方案二 : 本地局域网放行 ( 开发调试推荐 , 审核合规 )](#2、方案二 : 本地局域网放行 ( 开发调试推荐 , 审核合规 ))
- [3、方案三 : 全局允许所有 HTTP ( 仅本地临时调试 , 禁止上架 )](#3、方案三 : 全局允许所有 HTTP ( 仅本地临时调试 , 禁止上架 ))
- [4、商业环境 : 多环境配置封装案例](#4、商业环境 : 多环境配置封装案例)
- 三、注意事项与常见坑点排查
-
- [1、IP 地址配置的兼容性问题](#1、IP 地址配置的兼容性问题)
- 2、配置修改后不生效
- 3、常见报错与处理方案
-
- [报错 1 : App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.](#报错 1 : App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.)
- [报错 2 : 真机无法连接局域网 IP 接口 , 模拟器运行正常](#报错 2 : 真机无法连接局域网 IP 接口 , 模拟器运行正常)
- [报错 3 : 上架 App Store 被拒 , 提示 ATS 合规问题](#报错 3 : 上架 App Store 被拒 , 提示 ATS 合规问题)
- 4、安全规范建议
- 总结
参考文档 :
- Flutter 官方文档 : https://docs.flutter.dev/install/quick
- 使用出现网络问题 , 参考 在中国网络环境下使用 Flutter 文档 ;
- 使用 VS Code 开发 Flutter 环境安装 : https://docs.flutter.cn/install/with-vs-code
- VS Code 安装 : https://code.visualstudio.com/docs/setup/setup-overview

前言
在 移动应用 安全规范 不断收紧 的背景下 , 苹果自 iOS 9 系统起引入了 App Transport Security ( ATS , 应用传输安全 ) 机制 , 默认强制所有应用的网络请求必须使用 HTTPS 加密传输 , 直接拦截所有 HTTP 明文请求 ;
在 Flutter 跨平台开发场景中 , Android 平台默认允许 HTTP 请求 , 而 iOS 侧会因 ATS 规则导致 HTTP 接口直接请求失败 , 尤其在以下场景中配置需求十分普遍 :
- 本地开发调试阶段 , 连接局域网内的后端测试服务
- 对接企业内部历史系统 , 暂未完成 HTTPS 升级
- 模拟器本地联调 localhost 接口
- 部分公网第三方接口仅提供 HTTP 协议
本文将从 ATS 原理出发 , 详细讲解 Flutter iOS 端 HTTP 访问的多种配置方案、多环境商业项目封装实践 , 以及开发过程中的常见坑点与排查方案 ;
一、iOS ATS 机制概述
1、简介
ATS ( App Transport Security ) 是苹果系统内置的网络安全强制规范 , 作用于应用的所有网络请求底层 ;
Flutter 的 dio、http 等网络库最终均 调用 iOS 原生 URLSession 能力 , 因此同样受 ATS 约束 , 其默认规则为 :
- 所有网络请求必须使用 HTTPS 协议
- 服务端 TLS 版本不低于 1.2
- 证书必须符合苹果安全标准
未满足条件的 HTTP 明文请求会被系统直接拦截 , 抛出网络错误 , 无法正常请求数据 ;
2、核心原理
ATS 运行在 iOS 系统网络层 , 而非应用代码层 , 因此 仅修改 Flutter 端的网络请求代码无法绕过限制 ;
必须通过修改 iOS 工程的 Info.plist 配置文件 , 向系统声明 " 允许例外的域名/场景 " , 才能放行对应的 HTTP 请求 ;
苹果提供了三种层级的例外配置 , 安全等级从高到低分别为 : 指定域名例外 > 本地网络例外 > 全局放开例外 , 其中 全局放开方案在 App Store 审核中会被严格拦截 , 仅可用于本地开发 ;
二、配置操作步骤与方案详解
所有配置均需修改 iOS 工程下的 ios/Runner/Info.plist 文件 , 提供 " Xcode 可视化编辑 " 和 " 直接文本编辑 " 两种操作方式 , 以下分别讲解三种主流配置方案 ;
1、方案一 : 指定域名例外 ( 生产环境推荐 , 可正常上架 )
该方案仅对指定的域名放开 HTTP 权限 , 其余域名仍遵循 ATS 安全规则 , 符合苹果审核规范 , 是生产环境的唯一合规方案 ;
操作步骤
操作步骤 :
- 打开配置文件 : 打开 Flutter 项目 , 定位到
ios/Runner/Info.plist文件 - 选择编辑方式 :
- 方式 A 可视化编辑 : 右键用 Xcode 打开
Runner.xcworkspace, 在左侧项目导航中找到Info.plist进行可视化编辑 - 方式 B 修改配置文件 : 直接在 VS Code 中以文本/XML 形式打开
Info.plist
- 方式 A 可视化编辑 : 右键用 Xcode 打开
- 在根
<dict>标签内添加 ATS 配置 , 写入需要放行的域名 :
ios/Runner/Info.plist 添加配置示例 :
xml
<!-- ATS 放行所有HTTP明文请求 ( 测试环境使用 , 正式包建议指定域名而非全局放开 ) -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<!-- 替换为你的正式接口域名 , 无需添加 http:// 前缀 -->
<key>api.yourcompany.com</key>
<dict>
<!-- 允许该域名的所有子域名生效 , 如 v1.api.yourcompany.com -->
<key>NSIncludesSubdomains</key>
<true/>
<!-- 允许该域名使用 HTTP 明文请求 -->
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
<!-- iOS14+ 局域网设备访问权限文案 ( 内网调试接口才生效 , 公网IP无需 ) -->
<key>NSLocalNetworkUsageDescription</key>
<string>需要访问本地调试服务与业务接口获取数据</string>
<!-- 蜂窝/无线网络访问说明 , 用于系统权限弹窗与App Store审核 -->
<key>NSAppTransportNetworkUsageDescription</key>
<string>使用蜂窝网络或无线网络加载业务数据、请求服务接口</string>
Xcode 可视化操作对应项
- 添加
App Transport Security Settings( 类型为 Dictionary ) - 其子项添加
Exception Domains( 类型为 Dictionary ) - 在
Exception Domains下添加域名作为 Key , 类型为 Dictionary - 域名下添加
NSIncludesSubdomains= YES、NSExceptionAllowsInsecureHTTPLoads= YES
2、方案二 : 本地局域网放行 ( 开发调试推荐 , 审核合规 )
该方案专门放开 localhost、局域网 IP、.local 域名的 HTTP 权限 , 不会影响公网请求的安全规则 , 苹果审核允许该配置 , 是本地开发调试的最优解 ;
适用场景
- 模拟器连接本地电脑运行的后端服务
- 真机连接同一 WiFi 下的测试服务器 ( 192.168.x.x 等局域网 IP )
- 开发阶段需要频繁切换测试地址
ios/Runner/Info.plist 添加配置示例 :
xml
<!-- ATS 放行所有HTTP明文请求 ( 测试环境使用 , 正式包建议指定域名而非全局放开 ) -->
<key>NSAppTransportSecurity</key>
<dict>
<!-- 放行所有本地局域网、localhost 的 HTTP 请求 -->
<key>NSAllowsLocalNetworking</key>
<true/>
<!-- 可同时叠加正式域名例外 , 两者不冲突 -->
<key>NSExceptionDomains</key>
<dict>
<key>test-api.yourcompany.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
<!-- iOS14+ 局域网设备访问权限文案 ( 内网调试接口才生效 , 公网IP无需 ) -->
<key>NSLocalNetworkUsageDescription</key>
<string>需要访问本地调试服务与业务接口获取数据</string>
<!-- 蜂窝/无线网络访问说明 , 用于系统权限弹窗与App Store审核 -->
<key>NSAppTransportNetworkUsageDescription</key>
<string>使用蜂窝网络或无线网络加载业务数据、请求服务接口</string>
3、方案三 : 全局允许所有 HTTP ( 仅本地临时调试 , 禁止上架 )
该方案完全关闭 ATS 安全校验 , 允许所有 HTTP、HTTPS 请求 , 风险极高 , 提交 App Store 审核会直接被驳回 , 仅可用于纯本地开发、快速验证场景 ;
ios/Runner/Info.plist 添加配置示例 :
xml
<!-- ATS 放行所有HTTP明文请求 ( 测试环境使用 , 正式包建议指定域名而非全局放开 ) -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<!-- iOS14+ 局域网设备访问权限文案 ( 内网调试接口才生效 , 公网IP无需 ) -->
<key>NSLocalNetworkUsageDescription</key>
<string>需要访问本地调试服务与业务接口获取数据</string>
<!-- 蜂窝/无线网络访问说明 , 用于系统权限弹窗与App Store审核 -->
<key>NSAppTransportNetworkUsageDescription</key>
<string>使用蜂窝网络或无线网络加载业务数据、请求服务接口</string>
⚠️ 重要警告 : 正式打 Release 包、提交 App Store 时必须移除该配置 , 否则审核会被直接驳回 ;
4、商业环境 : 多环境配置封装案例
在企业级 Flutter 项目中 , 通常存在 Debug、Test、Release 多套环境 , 不同环境对 HTTP 的权限需求不同 ;
可通过 Xcode 构建配置分离 , 实现不同打包环境自动对应不同 ATS 规则 , 避免人工修改出错 ;
实现思路
- 在 Xcode 中为 Debug、Release 分别创建对应的
Info-Debug.plist、Info-Release.plist文件 - Debug 配置 : 包含
NSAllowsLocalNetworking+ 测试域名例外 - Release 配置 : 仅保留正式域名例外 , 移除所有调试相关配置
- 在 Xcode 的 Build Settings 中 , 为不同 Configuration 指定对应的 Info.plist 文件
Debug 环境完整配置示例
ios/Runner/Info.plist 添加配置示例 :
xml
<!-- Info-Debug.plist 节选 -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsLocalNetworking</key>
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>test-api.yourcompany.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
<key>pre-api.yourcompany.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
<!-- iOS14+ 局域网设备访问权限文案 ( 内网调试接口才生效 , 公网IP无需 ) -->
<key>NSLocalNetworkUsageDescription</key>
<string>需要访问本地调试服务与业务接口获取数据</string>
<!-- 蜂窝/无线网络访问说明 , 用于系统权限弹窗与App Store审核 -->
<key>NSAppTransportNetworkUsageDescription</key>
<string>使用蜂窝网络或无线网络加载业务数据、请求服务接口</string>
Release 环境完整配置示例
ios/Runner/Info.plist 添加配置示例 :
xml
<!-- Info-Release.plist 节选 -->
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>api.yourcompany.com</key>
<dict>
<key>NSIncludesSubdomains</key>
<true/>
<key>NSExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
</dict>
</dict>
生效验证
修改完成后执行以下命令 , 清理缓存并重新运行 , 确保配置生效 :
shell
flutter clean
cd ios && pod install && cd ..
flutter run
三、注意事项与常见坑点排查
1、IP 地址配置的兼容性问题
很多开发者会直接将 IP 地址写入 NSExceptionDomains , 该写法存在系统版本限制 :
- iOS 17 /iPadOS 17 及以上 : 官方支持直接将 IPv4/IPv6 地址、CIDR 网段作为
NSExceptionDomains的 Key - iOS 16 及更早版本 :
NSExceptionDomains仅识别域名 , 直接写 IP 完全不生效 , 请求仍会被 ATS 拦截
通用解决方案 : 调试阶段统一使用 NSAllowsLocalNetworking 放行局域网 IP , 无需单独写 IP 条目 , 可兼容全系统版本 ;
2、配置修改后不生效
这是最高频的踩坑场景 , 按以下步骤依次排查 :
- 未停止旧的 Flutter 进程 : 必须终止
flutter run后重新运行 , 热重载不会更新 Info.plist 配置 - 未清理构建缓存 : 执行
flutter clean+pod install后重新构建 - 设备 / 模拟器残留旧包 : 卸载应用后重新安装 , 旧包的配置会存在系统缓存
- 配置位置错误 : 必须放在
Info.plist根层级的 `` 标签内 , 不可嵌套在其他节点下
3、常见报错与处理方案
报错 1 : App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
- 原因 : ATS 拦截了 HTTP 明文请求
- 解决方案 : 根据业务场景选择上文三种方案之一 , 添加对应例外配置
报错 2 : 真机无法连接局域网 IP 接口 , 模拟器运行正常
- 原因 : iOS 14+ 真机访问本地网络需要用户授权 , 未添加权限描述会导致连接失败
- 解决方案 : 在 Info.plist 中添加
NSLocalNetworkUsageDescription权限说明字段
报错 3 : 上架 App Store 被拒 , 提示 ATS 合规问题
- 原因 : 使用了
NSAllowsArbitraryLoads = true全局放开配置 - 解决方案 : 移除全局配置 , 改为仅对必要域名添加例外规则
4、安全规范建议
- 生产环境必须使用 " 指定域名例外 " 方案 , 禁止全局放开 ATS
- 优先推动后端服务升级 HTTPS , ATS 例外仅作为过渡方案使用
- 测试 / 开发环境的宽松配置 , 严禁带入正式打包脚本
- 定期清理不再使用的例外域名 , 缩小安全攻击面
总结
本文完整讲解了 Flutter iOS 端配置 HTTP 访问的全流程方案 , 核心要点总结如下 :
-
底层机制 : iOS ATS 为系统级网络安全规则 , 会拦截所有 HTTP 明文请求 , 必须通过 Info.plist 配置例外才能放行
-
三种配置方案 :
- 指定域名例外 : 生产环境唯一合规方案 , 安全可控且可正常上架
- 本地局域网放行 : 开发调试首选 , 兼顾便利与安全 , 符合审核规范
- 全局放开 : 仅本地临时调试使用 , 正式包严禁使用 , 上架必被驳回
-
IP 配置限制 : iOS 16 及以下不支持 IP 作为例外域名 , 推荐用
NSAllowsLocalNetworking兼容全系统版本 -
商业项目实践 : 通过多环境 Info.plist 分离 , 实现开发 / 生产配置自动隔离 , 避免人工配置失误
-
常见问题 : 配置不生效优先检查缓存、旧包、权限描述;上架被拒优先排查全局放开配置
整体遵循 " 最小权限原则 " , 仅对必要的域名放开 HTTP 权限 , 优先推进 HTTPS 升级 , 才能同时满足开发效率、应用安全与审核合规的需求 ;