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

Swift+URLSession中MultipartFormData多部分请求边界用法排查

MultipartFormData 上传文件+JSON的边界格式修正方案

你当前的核心问题是手动构建多部分表单请求时,边界使用顺序和内容结构错误,导致服务器无法识别JSON数据。以下是具体的规则说明和代码修正方案:

正确的多部分请求格式规则

  • 必须设置正确的Content-Type头:请求的Content-Type需指定为 multipart/form-data; boundary=你的唯一边界字符串,这是服务器识别多部分请求的核心标识。
  • 边界的两种用法:
    • 分隔不同表单字段的分隔边界:格式为 --{boundary}\r\n(开头两个短横线 + 边界字符串 + 回车换行)
    • 标志整个请求结束的结束边界:格式为 --{boundary}--\r\n(开头两个短横线 + 边界字符串 + 结尾两个短横线 + 回车换行)
  • 单个表单字段的结构:
    1. 分隔边界
    2. Content-Disposition头:指定字段名,文件需额外添加; filename="文件名"
    3. Content-Type头:文件对应MIME类型,JSON指定application/json
    4. 两个连续的\r\n(分隔头信息与内容)
    5. 字段内容(文件数据或JSON数据)
    6. \r\n(结束当前字段)

你的代码存在的问题

  1. 过早添加结束边界:在文件部分后直接写入--\(boundary)--\r\n,服务器会判定请求已结束,后续JSON部分被视为无效内容,完全不会解析。
  2. JSON部分头信息顺序错误:应先写Content-Disposition指定字段名,再写Content-Type,你写反了顺序。
  3. JSON部分缺少分隔边界:每个新的表单字段都需要以分隔边界开头,你直接写入JSON头信息,服务器无法识别这是一个有效表单字段。

修正后的代码

// 第一步:设置关键的Content-Type请求头(必须添加!)
let boundary = UUID().uuidString // 用唯一随机字符串作为边界,避免与内容冲突
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")

var data = Data()

// 1. 构建文件上传部分
data.append("--\(boundary)\r\n".data(using: .utf8)!)
data.append("Content-Disposition: form-data; name=\"\(paramName)\"; filename=\"\(filename ?? \"filenamemissing\")\"\r\n".data(using: .utf8)!)
data.append("Content-Type: \(mimetype)\r\n\r\n".data(using: .utf8)!)
if let imageData = vidimg?.pngData() {
    data.append(imageData)
}
data.append("\r\n".data(using: .utf8)!) // 结束当前文件部分

// 2. 构建JSON数据部分
data.append("--\(boundary)\r\n".data(using: .utf8)!) // 分隔边界,开启新字段
data.append("Content-Disposition: form-data; name=\"jsonData\"\r\n".data(using: .utf8)!) // 先指定字段名
data.append("Content-Type: application/json\r\n\r\n".data(using: .utf8)!) // 再指定内容类型
data.append(jsonData)
data.append("\r\n".data(using: .utf8)!) // 结束当前JSON部分

// 3. 添加结束边界,标志整个请求完成
data.append("--\(boundary)--\r\n".data(using: .utf8)!)

// 设置内容长度
request.setValue(String(data.count), forHTTPHeaderField: "Content-Length")
request.httpBody = data

额外注意事项

  • 边界字符串要保证唯一,建议用UUID().uuidString生成,避免与文件、JSON内容重复导致解析失败。
  • 所有换行必须使用\r\n(CRLF格式),这是HTTP协议的强制要求,不能只用\n。
  • 确保jsonData是正确序列化的JSON数据(比如通过JSONSerialization.data(withJSONObject:options:)生成),避免JSON格式错误导致服务器无法解析。

内容的提问来源于stack exchange,提问作者user6631314

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 14:55:06