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

Swift上传PNG至FastAPI+S3后端报422错误求助

问题排查与解决方案

你的422错误根源在于Swift代码没有正确构建符合multipart/form-data规范的请求体,FastAPI无法解析格式错误的数据,具体问题及修复如下:

核心问题点

  • 缺少multipart/form-data必须的boundary参数:设置Content-Type时必须指定分隔符,否则服务器无法区分不同字段
  • 错误处理图片数据:直接将UIImage对象转为字符串拼接,不会生成有效的图片二进制数据
  • 请求体格式完全不符合multipart规范:没有按要求添加字段描述头(如Content-Disposition)和分隔边界

修正后的Swift代码

func uploadImage2(paramName: String, fileName: String, image: UIImage, uid: String) {
    guard let url = URL(string: "你的后端API地址") else {
        print("无效的URL")
        return
    }
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    
    // 生成随机boundary作为字段分隔符
    let boundary = UUID().uuidString
    request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
    
    let body = NSMutableData()
    
    // 添加file字段(图片数据)
    body.append("--\(boundary)\r\n".data(using: .utf8)!)
    body.append("Content-Disposition: form-data; name=\"file\"; filename=\"\(fileName)\"\r\n".data(using: .utf8)!)
    body.append("Content-Type: image/png\r\n\r\n".data(using: .utf8)!)
    // 将UIImage转为PNG二进制数据
    guard let pngData = image.pngData() else {
        print("无法将图片转为PNG格式")
        return
    }
    body.append(pngData)
    body.append("\r\n".data(using: .utf8)!)
    
    // 添加type字段
    body.append("--\(boundary)\r\n".data(using: .utf8)!)
    body.append("Content-Disposition: form-data; name=\"type\"\r\n\r\n".data(using: .utf8)!)
    body.append("image/png\r\n".data(using: .utf8)!)
    
    // 添加uid字段
    body.append("--\(boundary)\r\n".data(using: .utf8)!)
    body.append("Content-Disposition: form-data; name=\"uid\"\r\n\r\n".data(using: .utf8)!)
    body.append("\(uid)\r\n".data(using: .utf8)!)
    
    // 结束boundary
    body.append("--\(boundary)--\r\n".data(using: .utf8)!)
    
    request.httpBody = body as Data
    
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            print("请求错误: \(error.localizedDescription)")
            return
        }
        if let data = data {
            let responseString = String(data: data, encoding: .utf8)
            print("响应内容: \(responseString ?? "无法解析响应")")
        }
    }
    task.resume()
}

关键修复说明

  1. 添加boundary:通过UUID().uuidString生成唯一分隔符,在Content-Type中声明,确保服务器能正确拆分各个表单字段
  2. 正确处理图片数据:使用image.pngData()将UIImage转为PNG二进制数据,而非直接拼接对象字符串
  3. 符合multipart规范的字段封装:每个字段都需要用--boundary开头,添加Content-Disposition指定字段名、文件名(针对文件字段),然后是字段内容,最后用\r\n分隔

额外注意事项

  • 替换代码中的"你的后端API地址"为实际的FastAPI上传接口URL
  • 确保FastAPI接口的参数名(如file、type、uid)和代码中设置的name属性完全一致,否则也会触发422错误

内容的提问来源于stack exchange,提问作者Alp Doğukan Halitoğulları

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 23:50:28