使用 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 数组和字典,服务器响应

如何使用 REST API 中的 PUT 方法上传文件?

关于java中HashMap的put方法中的参数问题

AFNetworking3.2.1 Post请求通过httpbody传参

POST 和 PUT 请求中的问题,使用 axios、vuetify 数据表、vuejs