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

