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

如何处理Alamofire请求返回200状态码但无响应体的情况

问题场景

使用Alamofire向S3服务器上传文件,上传完成后返回200状态码但无响应体,触发错误:Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength。尝试设置.request(emptyResponseCodes:[200, 204, 205])和自定义fetchWithEmptyResponse方法均未解决,需要通过@escaping completionHandler正确传递空响应的成功结果。

解决方案

1. 自定义兼容空响应的序列化器

默认JSON响应序列化器会拒绝空数据,我们需要自定义序列化器,允许200状态码下的空响应,同时保留正常JSON数据的解析能力:

import Alamofire

class EmptyResponseCompatibleSerializer: ResponseSerializer {
    func serialize(request: URLRequest?, response: HTTPURLResponse?, data: Data?, error: Error?) throws -> Data? {
        // 优先处理错误
        if let error = error {
            throw error
        }
        
        guard let response = response else {
            throw AFError.responseValidationFailed(reason: .missingResponse)
        }
        
        // 200状态码+空数据视为成功,返回nil作为空标识
        if response.statusCode == 200 && (data == nil || data?.count == 0) {
            return nil
        }
        
        // 其他场景沿用默认JSON序列化逻辑
        return try JSONResponseSerializer().serialize(request: request, response: response, data: data, error: error)
    }
}

2. 调整请求调用逻辑

结合你的TargetType协议,修改请求发送代码,应用自定义序列化器,通过@escaping completionHandler传递结果:

func performRequest<T: TargetType>(target: T, completion: @escaping (Result<Void, Error>) -> Void) {
    AF.request(target)
        .validate(statusCode: 200..<300)
        .response(using: EmptyResponseCompatibleSerializer()) { response in
            switch response.result {
            case .success:
                // 200状态码无论是否有数据都判定为上传成功
                completion(.success(()))
            case .failure(let error):
                completion(.failure(error))
            }
        }
}

3. 针对S3上传的补充优化

如果上传请求使用.imageDataWithoutPath参数类型,可在TargetType扩展中补充设置Accept头,明确告知服务器接受空响应:

extension TargetType {
    public func asURLRequest() throws -> URLRequest {
        // 保留原有代码逻辑...
        
        // 新增:图片上传场景设置Accept头
        if case .imageDataWithoutPath(_) = parameters {
            urlRequest.setValue("*/*", forHTTPHeaderField: HTTPHeaderField.acceptType.rawValue)
        }
        
        return urlRequest
    }
}

关于emptyResponseCodes失效的说明

Alamofire的emptyResponseCodes仅对默认DataResponseSerializer生效,若请求默认使用JSON序列化器,该配置不会起作用——因为JSON序列化器本身会校验数据非空。因此必须通过自定义序列化器来兼容200状态码下的空响应场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 21:45:28