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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 18:27:41