使用 PUT 方法的 HTTPBody 中的数据失败,而它与 POST 一起使用?
Posted
技术标签:
【中文标题】使用 PUT 方法的 HTTPBody 中的数据失败,而它与 POST 一起使用?【英文标题】:Data in HTTPBody with a PUT method fails, while it works with a POST? 【发布时间】:2016-11-03 12:27:59 【问题描述】:首先我想说我遇到了与以下问题完全相同的问题:How to add data to HTTPBody with PUT method in NSURLSession?。但是没有人回答,所以我提出了自己的问题。
我们为学校作业编写了一个节点 API。我们已经测试了整个 API。 (那里出错的可能性很小。)
之后,我开始为 CRUD 用户开发 ios 客户端。 制作用户非常顺利,但是每当我尝试编辑用户时,就会发生一些奇怪的事情。服务器上的数据到达时未定义。
我使用以下代码来保存用户:
func saveUser(user: User, completionHandler: (String?, User?) -> Void)
let url = NSURL(string: "https://pokeapi9001.herokuapp.com/api/users/")
let request = NSMutableURLRequest(URL:url!)
request.HTTPMethod = "POST"
let postString = "email=\(user.email)&password=\(user.password!)&role=\(user.role)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
data, response, error in
if error != nil
print("error: \(error)")
do
guard let data = data else
throw JSONError.NoData
guard let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? NSDictionary else
throw JSONError.ConversionFailed
//do specific things
catch let error as JSONError
completionHandler(error.rawValue, nil)
catch let error as NSError
completionHandler(error.debugDescription, nil)
task.resume()
记住,这是完美的工作(不知道它是否打算这样使用)
要编辑用户,我使用以下代码:
func editUser(user: User, completionHandler: (String?, User?) -> Void)
let url = NSURL(string: "https://pokeapi9001.herokuapp.com/api/users/\(user.id!)")
let request = NSMutableURLRequest(URL:url!)
request.HTTPMethod = "PUT"
let postString = "email=\(user.email)&password=\(user.password!)&role=\(user.role)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
let task = NSURLSession.sharedSession().dataTaskWithRequest(request)
data, response, error in
if error != nil
print("error: \(error)")
do
guard let data = data else
throw JSONError.NoData
guard let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? NSDictionary else
throw JSONError.ConversionFailed
//do specific things
catch let error as JSONError
completionHandler(error.rawValue, nil)
catch let error as NSError
completionHandler(error.debugDescription, nil)
task.resume()
(原代码有点长,但我删除了与实际发布数据无关的部分)
我真的不知道我做错了什么,可能是一些小而愚蠢的事情。请帮忙。
在@fiks 输入后编辑
需要明确的是,我遇到的问题是我在 editUser 方法中填写“postString”的方式与在 saveUser 方法中填写的方式相同。(至少我认为是这样) 然而,在 saveUser 方法中,postString 似乎被正确地传递给了 API(它使用给定的值创建了一个新用户)。 editUser 方法不传递值。
如果我在服务器上放置控制台日志,它会显示所有值都是“未定义”。 为了测试 iOS 部分的 postString 是否正确,我打印了两个字符串。他们都输出了 email=user@test.com&password=test&role=admin
【问题讨论】:
不是 node.js 问题。错误的标签 您能否更具体地说明错误?能否请您与 Charles 核对请求并在此处发布? 对不起 Abhyudit,API 是用 Node.js 制作的,所以我想我应该把它添加进去。 @fiks 我遇到的问题是 let "postString" 中的数据在 POST(addUser) 请求中工作,但是在 PUT(editUser) 请求中它不起作用。如果我在 let postString = ... 之后进行打印,则打印输出: email=user@test.com&password=test&role=admin 正如预期的那样。但是在服务器上它说所有 3 个值都是未定义的。我将把它添加到我上面的问题中,以消除进一步的困惑。你能告诉我查尔斯是怎么工作的吗?我下载了它,但它并没有让我更聪明。感谢您的输入顺便说一句 @user2145124。关于查尔斯: 1. 运行查尔斯。 2. 在模拟器中运行应用程序。 3. 在 Charles 日志中查看您的应用程序发出的所有请求,并找到错误的请求。在那里,您将看到请求的所有详细信息。如果能发在这里就好了。 【参考方案1】:根据我在邮递员请求中看到的内容,您正在发送 x-www-form-urlencoded 请求。
您必须在代码中指定它。参见示例:POST request using application/x-www-form-urlencoded
关于 Charles:由于您使用的是 https,因此您必须为主机启用代理。更多信息在这里:https://www.charlesproxy.com/documentation/proxying/ssl-proxying/
【讨论】:
以上是关于使用 PUT 方法的 HTTPBody 中的数据失败,而它与 POST 一起使用?的主要内容,如果未能解决你的问题,请参考以下文章
带有 HTTPBody 问题的 Alamofire 数据发送
HTTPBody 中的 NSMutableRequest 数组和字典,服务器响应