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

POST空数据触发JSON解码错误及多语言本地化失效求助

问题1:空输入触发JSON解析错误

错误原因

当文本框为空时,服务器返回的不是预期的JSON格式数据,而是HTML内容(错误提示里的Unexpected character '<'说明返回了HTML标签,比如服务器错误页),导致JSONDecoder无法解析,抛出dataCorrupted错误。

解决步骤

1. 客户端前置参数校验

发起请求前先检查输入字段是否为空,直接提示用户,避免无效请求:

func signUp() {
    guard !name.isEmpty, !password.isEmpty, !phone.isEmpty else {
        errorMessage = "请填写所有必填字段"
        showAlert = true
        return
    }
    
    let parameters = [
        "name": name,
        "password": password,
        "mobile": phone,
    ]
    // 后续请求逻辑...
}

2. 网络请求中增加状态码与响应格式校验

修改userAuthRequest函数,先检查响应状态码,同时在解析失败时打印原始响应内容,方便排查服务器返回的具体内容:

func userAuthRequest<T>(url: String, parameters: [String : Any], type: T.Type) -> AnyPublisher<T, Error> where T : Decodable {
    guard let url = URL(string: url) else {
        return Fail(error: URLError(.badURL)).eraseToAnyPublisher()
    }
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.setValue("ar", forHTTPHeaderField: "lang") // 确保语言头设置正确
    
    let postData = parameters.map { "\($0)=\($1)" }
        .joined(separator: "&")
        .data(using: .utf8)
    request.httpBody = postData
    
    return URLSession.shared.dataTaskPublisher(for: request)
        .subscribe(on: DispatchQueue.global())
        .tryMap { response in
            // 检查状态码是否在正常范围
            guard (200...299).contains(response.response.statusCode) else {
                // 打印服务器返回的错误内容
                if let errorContent = String(data: response.data, encoding: .utf8) {
                    print("Server error response: \(errorContent)")
                }
                throw APIError.invalidStatusCode(response.response.statusCode)
            }
            return response.data
        }
        .decode(type: T.self, decoder: JSONDecoder())
        .mapError { error in
            // 统一处理错误类型
            if let decodingError = error as? DecodingError {
                print("Decoding error: \(decodingError)")
                return APIError.decodingFailed
            }
            return error
        }
        .eraseToAnyPublisher()
}

// 新增错误枚举(若未定义)
enum APIError: Error, LocalizedError {
    case badURL
    case invalidStatusCode(Int)
    case decodingFailed
    case serverError
    
    var localizedDescription: String {
        switch self {
        case .badURL:
            return "无效的URL"
        case .invalidStatusCode(let code):
            return "服务器错误,状态码:\(code)"
        case .decodingFailed:
            return "数据解析失败"
        case .serverError:
            return "服务器异常"
        }
    }
}
问题2:设置lang=ar仍返回英文

排查与修正方向

  1. 抓包验证请求头:用Charles/Proxyman等工具抓包,确认实际发送的请求中是否包含lang: ar的请求头。如果没有,检查代码中是否有其他逻辑覆盖了该请求头。
  2. 打印请求头确认:在userAuthRequest函数中添加打印,验证请求头设置是否生效:
print("Request headers: \(request.allHTTPHeaderFields ?? [:])")
  1. 避免请求头被覆盖:确保没有其他代码(如URLSession配置、拦截器)修改lang请求头,确认request.setValue("ar", forHTTPHeaderField: "lang")在所有请求头设置的最后执行。
  2. 核对服务器逻辑:如果抓包显示lang: ar已正确发送,但服务器仍返回英文,需确认服务器是否对该接口的语言判断有特殊规则(比如优先从参数而非请求头取语言),但Postman测试有效,所以大概率是代码端问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 06:23:12