【问题标题】:Swift POST request sends an empty bodySwift POST 请求发送一个空的正文
【发布时间】:2017-08-15 11:03:20
【问题描述】:

代码如下:

func makePOSTCall(endpoint: String, languageName: String) {
    guard let url = URL(string: endpoint) else {
        print("Could not create URL.")
        return
    }

    let requestLang: [String: Any] = ["name": languageName]
    let requestBody = try? JSONSerialization.data(withJSONObject: requestLang)

    var urlRequest = URLRequest(url: url)
    urlRequest.httpBody = requestBody
    urlRequest.httpMethod = "POST"
    let session = URLSession.shared
    let task = session.dataTask(with: urlRequest) {

        data, response, error in
        guard let data = data, error == nil else {
            print(error?.localizedDescription ?? "No data")
            return
        }

        let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
        if let responseJSON = responseJSON as? [String: Any] {
            print(responseJSON)
        }

    }
    task.resume()
}

这会向 Flask 发送一个 {"name": "Go"} JSON 字典。 Flask 应该将语言名称附加到一个数组并在响应中返回完整的数组。现在,这在我手动发送请求时有效,所以这不是 Flask 的错误。但是当我从 iOS 发送上述内容时,我在烧瓶控制台中得到 request.json == None 。显然,我发送的是一个空的身体,但我不应该发送。知道我哪里出错了吗?

我把函数称为

@IBAction func pressedMakePOSTCall(_ sender: UIButton) {

    makePOSTCall(endpoint: "http://127.0.0.1:5000/lang", languageName: "Go")

}

我尝试添加一个斜杠,只是在控制台中得到一个 404。我发现的唯一与我类似的问题是:How to make HTTP Post request with JSON body in Swift,我的代码基本相同。

【问题讨论】:

  • 你查过,JSONSerialization成功了吗,是requestBody不是nil?您也不应该将requestBody 定义为[String:Any],因为它的唯一值显然是String 类型,所以requestBody 应该是[String:String],但无论如何都不需要类型注释。
  • this works when I send the request manually 你这是什么意思?另外,你能检查一下requestBody的值吗?
  • 这种行为可能有不同的问题。我认为您还应该验证您传输的数据是否具有正确的编码。你应该尝试设置你的内容类型。因为如果预期的内容类型是 x-www-form-urlencoded 并且您正在发送 application/json,则服务器不会像您预期的那样接收或处理数据。
  • @DávidPásztor,print(requestBody) 给出可选的(13 个字节)。如果序列化失败不应该抛出吗?
  • 不,因为您使用的是try?,如果发生错误,它只会返回nil。仅当您使用嵌入在 do-catch 块中的 try 时才会引发错误,或者如果您使用 try! 并引发错误,则会出现不可恢复的运行时异常。但是,如果您的数据不为零,那么问题可能出在您的编码上。请包含来自其他来源(例如 Postman)的工作请求,以便我们可以在这里看到不同之处。

标签: ios json swift rest


【解决方案1】:

@weissja19 是正确的,我需要将内容类型设置为 application/json。添加

urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
urlRequest.setValue("application/json", forHTTPHeaderField: "Accept")

修复了错误。现在代码可以正常工作了。

附:我无法捕捉到它,因为我使用应用程序 Paw 进行测试,它会自动设置内容类型。

【讨论】:

    【解决方案2】:

    您可能需要手动操作:

    urlRequest.httpBody = "name=\(languageName)".data(using: .utf8)

    使用 JSONSerialization 会使您的 POST 正文像 {"name":"abc"} 一样,您的服务器可能不支持它

    【讨论】:

    • 这正是我想做的。 Flask 服务器在请求正文中收到 json 时会对其进行解析。我已经用 Paw 发送了手动请求,它们都顺利通过了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    • 2017-11-18
    • 1970-01-01
    • 2018-11-28
    • 2019-03-15
    • 2019-05-16
    相关资源
    最近更新 更多