Swift URLSession发送POST请求至PHP API时参数无法被接收问题
问题根因
你的请求格式和PHP端$_POST的解析规则不匹配:
- 现有Swift代码将参数序列化为raw JSON格式传输,
Content-Type设置为application/json - PHP的
$_POST超全局变量仅会自动解析application/x-www-form-urlencoded、multipart/form-data两种编码格式的POST请求体,不会主动解析JSON格式的请求体,这也是Android端调用正常的核心原因——Android端默认使用表单编码传参,符合$_POST的解析规则。
修复方案
无需修改PHP代码,仅需调整Swift端的参数编码逻辑,将参数编码为标准表单格式即可,完整可运行代码如下:
// 表单参数编码所需的字符集扩展 extension CharacterSet { static let formUrlEncodedValueAllowed: CharacterSet = { var allowed = CharacterSet.urlQueryAllowed allowed.remove(charactersIn: "&=+%") return allowed }() } static func submitNumber(parameters: [String: Any]){ print("parameters", parameters) guard let url = URL(string: Constants.phoneVerifyUrl) else { print("URL not found") return } // 替换原有JSON序列化逻辑,编码为x-www-form-urlencoded格式 let bodyComponents = parameters.map { key, value in let encodedKey = "\(key)".addingPercentEncoding(withAllowedCharacters: .formUrlEncodedValueAllowed) ?? "" let encodedValue = "\(value)".addingPercentEncoding(withAllowedCharacters: .formUrlEncodedValueAllowed) ?? "" return "\(encodedKey)=\(encodedValue)" } guard let httpBody = bodyComponents.joined(separator: "&").data(using: .utf8) else { print("参数编码失败") return } var request = URLRequest(url: url) request.httpMethod = "POST" request.httpBody = httpBody // 设置正确的表单Content-Type,移除原有JSON相关请求头 request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") let task = URLSession.shared.dataTask(with: request) { data, _, error in if let error = error { print("error", error.localizedDescription) return } guard let data = data else { print("No Data received") return } print("data", data) do { let decodedData = try JSONDecoder().decode(DataModels.self, from: data) DispatchQueue.main.async { print("noError", decodedData.noError) print("dataStr", decodedData.dataStr) } } catch { print("JSON error", error.localizedDescription) } } task.resume() }
改动点说明
- 移除原有的JSON序列化逻辑,将参数拼接为
key=value&key2=value2的标准表单格式,同时做了特殊字符百分号转义,避免特殊字符导致传参异常 - 将请求头
Content-Type从application/json替换为application/x-www-form-urlencoded,和Android端的请求编码格式完全一致 - 精简了冗余的分支判断逻辑,不改变原有响应处理的逻辑
修改完成后,PHP端可直接通过$_POST['phoneNumber']获取到传入的手机号参数,完全兼容现有多端调用的逻辑。
内容的提问来源于stack exchange,提问作者KANAYO AUGUSTIN UG
相关产品推荐
相关产品推荐

