15-10.【HTTP】HTTP Body 的常见格式有哪些?iOS 如何处理?

4 阅读2分钟

在 HTTP 通信中,Body(主体) 是承载实际业务数据的容器。服务器通过 Content-Type 请求头来判断如何解析这些二进制数据。

以下是 iOS 开发中最常见的四种 Body 格式及其处理方式:


1. JSON (application/json)

这是现代移动端开发(RESTful API)的绝对标准。数据结构清晰,易于跨平台解析。

  • iOS 处理方式:使用 JSONEncoder 将 Swift 结构体序列化为 Data

  • 代码示例

    Swift

    struct User: Encodable { let name: String; let id: Int }
    let user = User(name: "Gemini", id: 101)
    
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")
    // 将对象转为 Data 放入 Body
    request.httpBody = try? JSONEncoder().encode(user)
    

2. Form URL Encoded (application/x-www-form-urlencoded)

传统的浏览器表单提交格式。数据以键值对形式呈现,并经过 URL 编码,类似 name=Gemini&id=101

  • iOS 处理方式:手动拼接字符串并转换为 Data,或使用 URLComponents 构造查询字符串。

  • 代码示例

    Swift

    var components = URLComponents()
    components.queryItems = [
        URLQueryItem(name: "username", value: "admin"),
        URLQueryItem(name: "password", value: "123456")
    ]
    // 注意:这里取的是 query 字符串部分作为 Body
    request.httpBody = components.query?.data(using: .utf8)
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    

3. Multipart Form Data (multipart/form-data)

当请求中既有文本又有文件(如图片、视频)时,必须使用此格式。它通过一个特殊的 boundary 字符串将不同部分分隔开。

  • iOS 处理方式:原生 URLSession 处理起来比较繁琐,需要手动拼接复杂的二进制协议头;生产环境通常使用 Alamofire
  • 逻辑结构

4. Binary / Raw (application/octet-stream)

直接发送原始二进制流。常用于纯文件上传(如直接上传一个 .png.zip),不包含其他文本字段。

  • iOS 处理方式:直接读取文件 Data 并赋值给 httpBody

  • 代码示例

    Swift

    let imageData = UIImage(named: "avatar")?.jpegData(compressionQuality: 0.8)
    request.httpBody = imageData
    request.setValue("image/jpeg", forHTTPHeaderField: "Content-Type")
    

核心对比表

格式名称Content-Type适用场景iOS 核心工具
JSONapplication/json绝大多数 API、复杂嵌套数据JSONEncoder
Form...x-www-form-urlencoded登录、简单键值对、旧版接口URLComponents
Multipartmultipart/form-data混合上传(图片+描述)Data 拼接 / Alamofire
Plain Texttext/plain纯文本、简单的日志上传String.data(using:)

💡 避坑指南

  1. 忘记设置 Content-Type:这是最常见的错误。如果你发送了 JSON Body 但没设 Header,服务器可能会报 400 Bad Request
  2. Get 请求带 Body:虽然技术上可行,但 HTTP 规范不建议这样做,很多代理服务器(如 Nginx)会直接无视 GET 请求的 Body。
  3. 大文件上传:对于极大的文件,不要直接赋值给 request.httpBody(这会占用大量内存),而应使用 URLSession.shared.uploadTask(with:fromFile:)