You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

URLSession仅在蜂窝网络下随机失败问题求助

问题分析与解决:蜂窝网络下POST请求随机报错NSURLErrorDomain Code=-1005

错误本质

报错NSURLErrorDomain Code=-1005对应NSURLErrorNetworkConnectionLost,底层_kCFStreamErrorCodeKey=57是系统层面的ECONNRESET(连接被对端重置),说明请求已发送,但服务器或中间网络节点主动断开了连接。结合你描述的场景(模拟器/WiFi正常、蜂窝随机失败、其他测试APP可正常调用),问题大概率出在请求适配或蜂窝网络的特殊限制上。

可能原因及解决方法

1. 蜂窝网络MTU限制导致分片传输异常

蜂窝网络的MTU(最大传输单元)通常比WiFi小(WiFi多为1500字节,蜂窝可能低至1400字节),如果请求体过大,蜂窝网络下会触发IP分片,部分网络环境中服务器无法正确拼接分片包,进而主动断开连接。

解决方法:

  • 对请求体进行gzip压缩:
    if let compressedData = try? jsonData.gzipped() {
        request.httpBody = compressedData
        request.setValue("gzip", forHTTPHeaderField: "Content-Encoding")
    }
    
  • 若业务允许,拆分大请求为多个小请求。

2. URLSession默认配置未适配蜂窝网络波动

默认URLSession的超时设置偏短,且未针对蜂窝网络的不稳定做重试处理,容易因短暂网络波动触发连接丢失错误。

解决方法:

  • 自定义Session配置,延长超时并优化连接策略:
    let config = URLSessionConfiguration.default
    config.timeoutIntervalForRequest = 30 // 延长请求超时至30秒
    config.timeoutIntervalForResource = 60
    config.httpMaximumConnectionsPerHost = 5
    let session = URLSession(configuration: config)
    
    // 使用自定义Session发起请求
    let (data, response) = try await session.data(for: request)
    
  • 手动实现针对-1005错误的有限重试逻辑:
    func sendRequest(with request: URLRequest, retryCount: Int = 2) async throws -> (Data, URLResponse) {
        do {
            return try await URLSession.shared.data(for: request)
        } catch let error as NSError where error.code == -1005 && retryCount > 0 {
            return try await sendRequest(with: request, retryCount: retryCount - 1)
        } catch {
            throw error
        }
    }
    

3. 服务器对蜂窝网络IP/请求头的特殊限制

部分服务器会对蜂窝网络IP段做限流,或对iOS默认请求头(如User-Agent)在蜂窝环境下有异常处理逻辑。

解决方法:

  • 给请求添加明确的User-Agent头,模拟正常工作的测试APP的UA:
    request.setValue("Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148", forHTTPHeaderField: "User-Agent")
    
  • 联系后端团队检查服务器日志,确认蜂窝网络IP的请求是否被异常拦截或重置。

4. 运营商私有DNS/代理干扰HTTPS连接

部分运营商的私有DNS或代理对HTTPS请求的处理存在异常,导致连接中途断开。

解决方法:

  • 在Info.plist中配置ATS规则,针对目标域名放宽限制(仅用于测试排查):
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExtendsExceptionDomains</key>
        <dict>
            <key>blahblah</key>
            <dict>
                <key>NSExceptionRequiresForwardSecrecy</key>
                <false/>
                <key>NSIncludesSubdomains</key>
                <true/>
            </dict>
        </dict>
    </dict>
    
  • 引导用户关闭手机「私有DNS」功能(路径:设置->蜂窝网络->蜂窝数据选项->DNS->选择「自动」)。

排查验证步骤

  1. 用Charles或Wireshark抓包,对比WiFi和蜂窝网络下的请求差异,重点查看请求头、请求体大小、传输分片情况。
  2. 测试不同大小的请求体,确认是否仅大请求触发错误。
  3. 更换不同运营商的SIM卡,排除运营商网络差异导致的问题。

内容的提问来源于stack exchange,提问作者erotsppa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 16:58:37