Swift POST 请求发送一个空的正文
Posted
技术标签:
【中文标题】Swift POST 请求发送一个空的正文【英文标题】:Swift POST request sends an empty body 【发布时间】: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)的工作请求,以便我们可以在这里看到不同之处。
【参考方案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 发送了手动请求,它们都顺利通过了。以上是关于Swift POST 请求发送一个空的正文的主要内容,如果未能解决你的问题,请参考以下文章