Swift上传图片到后端报invalid_image,Postman和后台页上传正常如何解决
Swift 端 multipart/form-data 上传图片返回
invalid_image 错误解决 问题现象
后端图片上传接口在后台管理页面、Postman测试时均可以正常上传,但是通过Swift APP上传时始终返回invalid_image错误。
初始实现代码
实现逻辑为获取UIImage后调用pngData()转换为二进制数据,通过URLSession发送multipart/form-data格式请求,图片对象存储在param["src"]中,初始错误代码如下:
var request = URLRequest(url: URL(string: ServerURL)!,timeoutInterval: Double.infinity) let boundary = "Boundary-\(UUID().uuidString)" request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") request.httpMethod = "PUT" var body = "" for param in parameters { if param["disabled"] == nil { let paramName = param["key"]! body += "--\(boundary)\r\n" body += "Content-Disposition: form-data; name=\"\(paramName)\"" if param["contentType"] != nil { body += "\r\nContent-Type: \(param["contentType"] as! String)" } let paramType = param["type"] as! String if paramType == "text" { let paramValue = param["value"] as! String body += "\r\n\r\n\(paramValue)\r\n" } else { let paramSrc = param["src"] as! UIImage // 错误点:将图片二进制数据强制转为UTF-8字符串,会破坏数据结构 let fileData = (String(data: fileData, encoding: .utf8) ?? "Converting to UTF8 Fail") as String body += "; filename=\"myImg.png\"\r\n" body += "Content-Type: image/png\r\n\r\n\(fileData)\r\n" } } }
排查过程
- 首先检查发现
paramSrc中的UIImage内容正常,但转换得到的fileData为空,是因为图片二进制数据本身不符合UTF-8编码规则,转换会失败。 - 尝试修改代码直接获取图片二进制数据:
let fileData = paramSrc.pngData()! as NSData
修改后fileData已经有正常数据,但上传仍然报错,报错信息如下:
ErrorDetail(string='Upload a valid image. The file you uploaded was either not an image or a corrupted image.', code='invalid_image')
最终解决方案
根本原因为整个请求体使用String类型构造,就算拿到了正确的图片二进制数据,拼接进String时仍然会发生编码转换,破坏图片的二进制结构。
正确的实现方式是使用NSMutableData(或者Swift原生Data)类型构造整个请求体:
- 文本参数部分将字符串转成UTF-8编码的Data拼接到请求体中
- 图片二进制数据直接拼接,不做任何字符串转换
- 最后拼接请求收尾的
--\(boundary)--标记
该问题由@pastre协助定位解决。
内容的提问来源于stack exchange,提问作者Bosoud
相关产品推荐
相关产品推荐

