Swift调用API上传图片时数据损坏为空且后台提示缺少'file'参数
问题根因分析
- 二进制数据强制转字符串导致损坏:PNG图片是二进制格式,不存在UTF-16编码的文本表达,原有代码用
String(data: fileData!, encoding: .utf16)转换会直接返回nil,最终写入请求体的是Optional(nil)字符串,完全丢失原始图片数据,这是图片大小只有1KB无法打开的直接原因。 - 请求体编码不符合规范:multipart/form-data 标准使用UTF-8编码,原有代码最终把body转成UTF-16编码的Data,后端Spring Boot按UTF-8解析时完全识别不到正确的字段结构,所以抛出
Required request part 'file' is not present错误。 - Content-Type字段值错误:图片部分的Content-Type写死为
"content-type header",不符合MIME类型规范,正确值应为image/png。 - 请求体构造逻辑错误:二进制文件不能拼接到String类型的body中,应该直接用
Data类型拼接整个请求体,避免编码转换损失数据。
额外提示:如果当前代码在主线程执行,
semaphore.wait()会阻塞主线程导致UI卡死,建议删除信号量逻辑,改用异步回调处理接口返回结果。
修正后代码
func use() { let semaphore = DispatchSemaphore(value: 0) let boundary = "Boundary-\(UUID().uuidString)" // 用NSMutableData直接拼接二进制请求体,避免编码转换损失 let body = NSMutableData() // 拼接file字段的头部信息 body.append("--\(boundary)\r\n".data(using: .utf8)!) body.append("Content-Disposition: form-data; name=\"file\"; filename=\"k.png\"\r\n".data(using: .utf8)!) body.append("Content-Type: image/png\r\n\r\n".data(using: .utf8)!) // 直接添加图片二进制数据,不做字符串转换 if let imageData = UIImage(data: self.picData)?.pngData() { body.append(imageData) } body.append("\r\n".data(using: .utf8)!) // 拼接请求结束边界 body.append("--\(boundary)--\r\n".data(using: .utf8)!) var request = URLRequest(url: URL(string: "替换为你的实际接口地址")!, timeoutInterval: 30) request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") request.httpMethod = "POST" request.httpBody = body as Data let task = URLSession.shared.dataTask(with: request) { data, response, error in defer { semaphore.signal() } if let error = error { print("请求失败:\(error.localizedDescription)") return } if let data = data, let resStr = String(data: data, encoding: .utf8) { print("接口返回:\(resStr)") } } task.resume() semaphore.wait() }
内容的提问来源于stack exchange,提问作者Sunsar Purewal
相关产品推荐
相关产品推荐

