Swift4+中POST请求发送数组数组问题:Insomnia生成代码多参数报错
解决Swift 4+中Multipart/Form-Data多键值对POST请求失败的问题
我刚遇到过几乎一模一样的问题!Insomnia生成的这段代码忽略了multipart/form-data格式的两个关键要求,这就是为什么多参数时服务器完全解析不到数据的原因。
原代码的核心问题
- 缺少参数块结尾的换行:每个表单字段的内容结束后必须添加
\r\n,单参数时服务器可能容错了格式错误,但多参数时会导致后续字段被解析成前一个字段的内容。 - 没有添加结束边界:整个请求体的最后必须以
--\(boundary)--\r\n结尾,告诉服务器请求体结束,原代码完全遗漏了这部分。 - 强制解包风险:
param["name"]!这种强制解包会导致参数格式错误时直接崩溃,不够安全。
修复后的完整代码
import Foundation let headers = [ "accept": "application/json" ] let parameters = [ ["name": "email", "value": "example@gmail.com"], ["name": "token", "value": "911"] ] let boundary = "---011000010111000001101001" var body = "" do { for param in parameters { guard let paramName = param["name"] else { print("Missing 'name' in parameter") continue } body += "--\(boundary)\r\n" body += "Content-Disposition: form-data; name=\"\(paramName)\"\r\n" if let filename = param["fileName"], let contentType = param["content-type"] { let fileContent = try String(contentsOfFile: filename, encoding: .utf8) body += "Content-Type: \(contentType)\r\n" body += "Content-Disposition: form-data; name=\"\(paramName)\"; filename=\"\(filename)\"\r\n\r\n" body += fileContent + "\r\n" // 字段内容结尾添加换行 } else if let paramValue = param["value"] { body += "\r\n\(paramValue)\r\n" // 字段内容结尾添加换行 } } // 添加multipart请求的结束边界 body += "--\(boundary)--\r\n" } catch { print("Error building request body: \(error.localizedDescription)") } var request = URLRequest(url: URL(string: "https://server.../verify")!, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0) request.httpMethod = "POST" request.allHTTPHeaderFields = headers // 手动设置正确的Content-Type头,包含boundary request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type") if let postData = body.data(using: .utf8) { request.httpBody = postData } else { print("Failed to convert body string to data") } let session = URLSession.shared let dataTask = session.dataTask(with: request) { data, response, error in if let error = error { print("Request error occurred: \(error)") return } guard let httpResponse = response as? HTTPURLResponse else { print("Received invalid response") return } print("Response status code: \(httpResponse.statusCode)") if let data = data, let responseString = String(data: data, encoding: .utf8) { print("Response body:\n\(responseString)") } } dataTask.resume()
额外优化说明
- 安全处理可选值:用
guard和if let替代强制解包,避免运行时崩溃。 - 规范格式顺序:调整了文件上传时的Content-Type和Content-Disposition顺序,符合RFC标准。
- 明确Content-Type:手动设置包含boundary的Content-Type头,避免原代码中可能出现的头信息不一致问题。
内容的提问来源于stack exchange,提问作者J A S K I E R
相关产品推荐
相关产品推荐

