URLSession.dataTask调用异常:传URL正常,传Request返回数据含尾部无效内容
解决URLSession.dataTask用Request调用时返回数据尾部的无效内容问题
嘿,这个问题我之前帮朋友排查过类似的,咱们一步步拆解来解决。
首先得明确:当你直接用URL调用dataTask时,URLSession会自动帮你生成一个默认的URLRequest,而你手动构建的Request大概率和这个默认请求存在差异——这就是问题的根源。
先排查Request和默认请求的差异
你可以先把两种请求的细节打印出来对比,比如:
// 打印默认请求的信息 let url = URL(string: "\(basePath)/userDetails?prefixText=\(prefixText)")! let defaultRequest = URLRequest(url: url) print("默认请求头:\(defaultRequest.allHTTPHeaderFields ?? [:])") print("默认缓存策略:\(defaultRequest.cachePolicy)") print("默认HTTP方法:\(defaultRequest.httpMethod ?? "GET")") // 打印你自己构建的Request信息 var yourRequest = URLRequest(url: url) // 这里是你原来的Request设置代码 print("自定义请求头:\(yourRequest.allHTTPHeaderFields ?? [:])") print("自定义缓存策略:\(yourRequest.cachePolicy)") print("自定义HTTP方法:\(yourRequest.httpMethod ?? "GET")")
重点对比这几个点:
- 请求头:尤其是
Accept、Content-Type这类字段,默认请求的Accept通常是*/*,如果你手动设置了application/json但服务器不支持,可能返回额外的错误信息或者格式不对的内容。 - 缓存策略:如果你的Request设置了
returnCacheDataElseLoad这类策略,可能导致本地旧缓存和新响应数据混在一起,出现尾部无效内容。 - HTTP方法:确保你自定义的Request和默认请求的方法一致(默认GET),别不小心写成了POST或者其他方法。
检查数据解析和响应内容
如果请求细节完全一致,那就要看响应数据本身了:
- 对比两种方式返回的
data.count,如果自定义Request返回的data长度更长,说明服务器确实返回了额外内容,这时候需要抓包看服务器的响应(用Charles或者Xcode的网络调试工具),检查响应头的Content-Length是否和data长度匹配——如果不匹配,可能是服务器端的问题,或者中间代理附加了内容。 - 如果data长度一致,但解析后有无效内容,那可能是编码问题。比如用
String(data: data, encoding: .utf8)时,数据里有非UTF8字节,导致乱码。可以尝试用String(data: data, encoding: .isoLatin1)临时查看原始内容,或者直接打印data的十六进制值,对比两种方式的差异。
尝试用默认配置的Session测试
有时候自定义的URLSession配置也会导致问题,你可以创建一个完全默认的Session来测试:
let defaultConfig = URLSessionConfiguration.default let freshSession = URLSession(configuration: defaultConfig) let task = freshSession.dataTask(with: yourRequest) { data, response, error in guard let data = data else { return } // 这里解析数据,看是否还有无效内容 if let content = String(data: data, encoding: .utf8) { print(content) } } task.resume()
如果这样就正常了,说明你原来的Session配置有问题,比如缓存、HTTP/2设置等。
最后总结
90%的概率是你手动构建的URLRequest和默认请求存在细节差异,导致服务器返回了异常响应。通过对比请求信息、抓包分析响应,很快就能定位到问题。如果还是解决不了,可以把两种请求的完整信息和响应数据贴出来,咱们再进一步排查。
内容的提问来源于stack exchange,提问作者Deepali
相关产品推荐
相关产品推荐

