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

Swift构造HTTP POST form-data请求体格式错误问题排查

问题根因

你构造的multipart/form-data请求体存在3个不符合规范的问题,是触发400错误的直接原因:

  • 冗余传参:你错误将type: image/jpeg作为独立表单项提交,但对照Postman成功请求、官方curl示例可以确认,该接口仅接收两个表单项:messaging_product和file。type=image/jpeg是file字段的附属属性,不属于独立参数,Meta Graph接口对冗余参数会直接判定请求非法。
  • 普通表单项缺少头部分隔空行:按照multipart/form-data规范,每个表单项的头部信息写完后,必须追加一个空行(连续两个\r\n)才能拼接字段值。你的代码在写完普通字段的Content-Disposition头后直接拼接字段值,没有空行分隔,服务端解析时会把字段值识别为头部内容,无法正确读取参数。
  • 文件表单项同样缺少头部分隔空行:文件字段的Content-Type头部写完后,你直接拼接了图片二进制数据,同样缺少分隔用的空行,服务端无法正确识别文件内容的起始位置。
修正步骤
  1. 移除冗余参数,调用时的parameters仅保留必填项:
let parameters = ["messaging_product": "whatsapp"]
  1. 重写createBody方法,补全所有分隔空行,对齐标准multipart格式:
private func createBody(withParameters parameters: [String: String], imageData: Data, boundaryString: String) -> Data {
    let body = NSMutableData()
    let boundaryPrefix = "--\(boundaryString)\r\n"
    let filename = "upload.jpg"
            
    // 拼接普通参数
    for (key, value) in parameters {
        body.append(boundaryPrefix.data(using: .utf8)!)
        body.append("Content-Disposition: form-data; name=\"\(key)\"\r\n\r\n".data(using: .utf8)!)
        body.append("\(value)\r\n".data(using: .utf8)!)
    }
    
    // 拼接文件参数
    body.append(boundaryPrefix.data(using: .utf8)!)
    body.append("Content-Disposition: form-data; name=\"file\"; filename=\"\(filename)\"\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("--\(boundaryString)--\r\n".data(using: .utf8)!)
    
    return body as Data
}
调试建议

修改完成后如果仍有报错,可以在赋值request.httpBody前将请求体转成字符串打印,和Postman的原始请求体逐行比对结构:

if let debugStr = String(data: requestData, encoding: .utf8) {
    print("请求体结构:\n\(debugStr)")
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 16:06:29