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

Swift中POST请求接收JSON时出现无效JSON错误求助

解决POST请求JSON格式错误问题

我向后端发送POST请求时遇到如下错误:“The given data was not valid JSON.”,底层错误信息为Optional(Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.})
以下是我用于发送/获取数据的代码:

func fetchDataWithParameters(){
    struct Response: Codable {
        // 这里是Response结构体的内容(用户代码未完整展示)
    }
    // 发送请求的逻辑(用户代码未完整展示)
}

我来帮你排查这个问题,结合错误信息来看,核心问题是你发送的请求体或者后端返回的响应不是标准的JSON结构(标准JSON必须以数组[]或对象{}开头),下面是具体的原因分析和解决办法:

1. 发送的请求体是JSON片段而非标准结构

这个错误最常见的场景是:你直接发送了单个值(比如字符串、数字)作为请求体,而不是用对象或数组包裹起来。举个例子,你发了"hello world",但标准JSON要求你发{"content": "hello world"}或者["hello world"]。

解决办法:

  • 调整你的请求体构造逻辑,把参数包装成字典(对象)或数组:
    // 正确示例:用字典包装参数
    let params = ["username": "testUser", "age": 25]
    request.httpBody = try? JSONSerialization.data(withJSONObject: params)
    
  • 如果后端确实要求接收单个值(这种场景比较少见),你可以在解析响应时开启允许JSON片段的设置(iOS 13+支持):
    let decoder = JSONDecoder()
    if #available(iOS 13.0, *) {
        decoder.allowFragments = true
    }
    // 然后用这个decoder解析响应
    

2. 请求头未正确设置Content-Type

如果你的请求头里没有指定Content-Type: application/json,后端可能无法识别你发送的是JSON数据,甚至返回非JSON格式的错误响应,导致解析失败。

解决办法:

添加请求头的代码示例:

var request = URLRequest(url: yourAPIURL)
request.httpMethod = "POST"
// 必须添加这个请求头
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
// 后续设置请求体...

3. 后端返回的响应不是合法JSON

有时候错误提示的是“请求数据无效”,但实际是后端返回的内容不是标准JSON(比如返回了HTML错误页面、纯文本提示)。你可以先打印出原始响应内容确认:

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    if let data = data {
        let rawResponse = String(data: data, encoding: .utf8)
        print("后端原始响应:\(rawResponse ?? "无法解码")")
    }
    // 其他逻辑...
}
task.resume()

如果发现返回的不是JSON,你需要和后端开发者沟通,确认接口的返回格式是否正确。

4. JSON序列化时出错

如果你用JSONSerialization序列化自定义对象,会导致序列化失败,发送的请求体可能是空或者无效内容。这种情况下建议用JSONEncoder来序列化遵循Encodable协议的自定义对象:

// 定义请求数据模型
struct UserRequest: Encodable {
    let username: String
    let password: String
}

// 构造请求数据
let userRequest = UserRequest(username: "test", password: "123456")
// 序列化
request.httpBody = try? JSONEncoder().encode(userRequest)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:54:35