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

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()

额外优化说明

  1. 安全处理可选值:用guard和if let替代强制解包,避免运行时崩溃。
  2. 规范格式顺序:调整了文件上传时的Content-Type和Content-Disposition顺序,符合RFC标准。
  3. 明确Content-Type:手动设置包含boundary的Content-Type头,避免原代码中可能出现的头信息不一致问题。

内容的提问来源于stack exchange,提问作者J A S K I E R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:07:45