Swift多部分文件上传报错:Required request part 'file' is not present
头像上传Multipart请求报错:Required request part 'file' is not present
问题代码
尝试通过Multipart文件上传方式上传头像,Swift实现代码如下:
func uploadPhoto(image: UIImage, filePath: String, completion: @escaping uploadPhotoClosure) { let imageData = image.jpegData(compressionQuality: 0.3) let url = "https:www.somepath.com/uploadFile" var request = URLRequest(url: URL(string: url)!) request.httpMethod = "POST" let boundary = UUID().uuidString let contentType = "multipart/form-data; boundary=\(boundary)" request.addValue(contentType, forHTTPHeaderField: "Content-Type") request.addValue("application/json", forHTTPHeaderField: "Accept") var body = Data() body.append("\r\n--\(boundary)--\r\n".data(using: String.Encoding.utf8)!) body.append("Content-Disposition: form-data; name=\"file\"\r\n\r\n".data(using: String.Encoding.utf8)!) body.append("field_mobileinfo_image".data(using: String.Encoding.utf8, allowLossyConversion: true)!) body.append("\r\n--\(boundary)\r\n".data(using: String.Encoding.utf8)!) body.append("Content-Disposition: form-data; name=\"files[field_mobileinfo_image]\"; filename=\"img.jpg\"\r\n".data(using: String.Encoding.utf8)!) body.append("Content-Type: application/octet-stream\r\n\r\n".data(using: String.Encoding.utf8)!) body.append(imageData!) body.append("\r\n--\(boundary)\r\n".data(using: String.Encoding.utf8)!) request.httpBody = body self.serviceManager.async(request: request) { (innerClosure) in do { let response = try innerClosure() guard let json = response.jsonObject else { completion({ throw JSONErrorType.parsingError }) return } let jsonData = try JSONSerialization.data(withJSONObject: json, options: []) let responseModel = try JSONDecoder().decode(EditProfilePhotoUploadResponse.self, from: jsonData) completion({ return responseModel }) } catch { completion({ throw error }) } } } //servicemanager class func async(request: URLRequest, completion: @escaping ServiceManagerAsyncCompletion) { ServiceManager.log(request) let task = self.urlSession.dataTask(with: request) { (data, response, error) in guard error == nil else { DispatchQueue.main.async { completion({ throw error! }) } return } guard let response = response as? HTTPURLResponse else { DispatchQueue.main.async { completion({ throw ServiceErrorType.invalidResponse }) } return } ServiceManager.log(response, withBody: data) //here handling status code } }
服务器错误响应
{ "status" : 500, "message" : "Required request part 'file' is not present", "timestamp" : "2022-08-05T05:30:55.415+0000", "path" : "/uploadFile", "error" : "Internal Server Error" }
解决建议
- 修正Multipart边界格式:请求体开头错误使用了闭合边界
--\(boundary)--,正确结构应以起始分隔符--\(boundary)开头,字段间用--\(boundary)分隔,最终用--\(boundary)--闭合。 - 匹配服务器要求的字段名:服务器提示缺少
file字段,当前代码中文件字段名为files[field_mobileinfo_image],与要求不符。需将该字段名改为name="file",同时移除多余的file字符串字段(即那段field_mobileinfo_image文本)。 - 调整请求体拼接逻辑:正确的Multipart文件上传请求体示例:
guard let imageData = image.jpegData(compressionQuality: 0.3) else { completion({ throw UploadError.failedToConvertImage }) return } var body = Data() // 起始分隔符 body.append("--\(boundary)\r\n".data(using: .utf8)!) // 文件字段 body.append("Content-Disposition: form-data; name=\"file\"; filename=\"img.jpg\"\r\n".data(using: .utf8)!) body.append("Content-Type: image/jpeg\r\n\r\n".data(using: .utf8)!) body.append(imageData) body.append("\r\n".data(using: .utf8)!) // 闭合边界 body.append("--\(boundary)--\r\n".data(using: .utf8)!) - 修复URL格式:当前URL
https:www.somepath.com/uploadFile缺少//,应改为https://www.somepath.com/uploadFile,避免请求地址无效。 - 处理可选值安全问题:移除
imageData!的强制解包,添加空值判断,防止因图片转换失败导致崩溃。
内容的提问来源于stack exchange,提问作者Anilkumar iOS Developer
相关产品推荐
相关产品推荐

