如何在 Alamofire 中请求带有正文和标头的 JSON?

Posted

技术标签:

【中文标题】如何在 Alamofire 中请求带有正文和标头的 JSON?【英文标题】:How to request JSON with body and header in Alamofire? 【发布时间】:2017-07-19 10:23:52 【问题描述】:

我曾尝试使用以下代码进行请求,但结果出现 400 错误。 API 由 header 和 body 组成。标头有两个字段,即“授权”和“内容类型”。正文格式已添加到下面的参数中。

    func file( sender: abc)

        let baseUrl = "url”

        let params: [String : Any] = [
            "profile": [
                “Type": [
                    " Real Estate",
                    "Estater",
                    "Construction",
                    "Entertainment"
                ],
                "Size": [
                    "large",
                    “small”
                ],
                "Level": [
                    “A”,
                    “B”
                ],
                “Name” : [
                    “John”,
                    “Harry”
                ]
            ]
        ]

        let header = [
            "Authorization" : "bearer e2ff3aa3-63a3-41d1-bc5a-3e8c88adeaaa",
            "Content-Type" : "application/json"
        ]

//        var request = URLRequest(url: URL(string:baseUrl)!)
//        request.httpMethod = HTTPMethod.post.rawValue
//        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
//        request.addValue("bearer e2ff3aa3-63a3-41d1-bc5a-3e8c88adeaaa", forHTTPHeaderField: "Authorization")
//        let data = try! JSONSerialization.data(withJSONObject: params as Any, options:JSONSerialization.WritingOptions.prettyPrinted)
//        
//        request.httpBody = data

        Alamofire.request("\(baseUrl)", method: .post, parameters: params, headers:header).responseJSON  response in
            print(response.request ?? "no request")  // original URL requ est
            print(response.response ?? "no response") // HTTP URL response
            print(response.data ?? "no data")     // server data
            print(response.result)   // result of response serialization
            print(response.response?.statusCode ?? "noCode")

            if(response.response?.statusCode != nil)
                switch response.response!.statusCode 
                case 200:
                    print("Success")
                    let json = JSON(data: response.data!)
                    print(json)
                    sender.onSuccessCall()
                case 400:
                    print("Error in authentication")
                case 401:
                    print("Error authentication object was not found")
                default:
                    print("dEfault")
                
            
        
    

请帮忙解决这个问题。

【问题讨论】:

我们不知道你的 api 想要你做什么 我只想通过 post 请求获取 JSON 数据,但它显示 400 错误。我的代码有错误吗? 在不知道您的 API 期望什么的情况下,我们无能为力。请在您的问题中包含一个成功的请求,即使它不是来自 swift(即 Postman 请求、curl 请求等)。 如果响应中出现错误,甚至在 seding 数据之前我们也无能为力,信息太少 请尝试使用我的代码,看看它对我来说非常适合我已经用我的 magento api 测试过 【参考方案1】:

我解决了问题,下面添加了正确的方法。

   func file( sender: abc)

    let params: [String : Any] = [
        "profile": [
            “Type": [
                " Real Estate",
                "Estater",
                "Construction",
                "Entertainment"
            ],
            "Size": [
                "large",
                “small”
            ],
            "Level": [
                “A”,
                “B”
            ],
            “Name” : [
                “John”,
                “Harry”
            ]
        ]
    ]

var request = URLRequest(url: URL(string:”url string”)!)
    request.httpMethod = HTTPMethod.post.rawValue
    request.setValue("bearer 5bac059b-eb2b-4e1b-914a-9de5b6a58577", forHTTPHeaderField: "Authorization")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")

    let data = try! JSONSerialization.data(withJSONObject: params as Any, options:JSONSerialization.WritingOptions.prettyPrinted)

   let json = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
    print(json!)

    request.httpBody = json!.data(using: String.Encoding.utf8.rawValue)

    Alamofire.request(request).responseJSON  response in
        print(response.request ?? "no request")  // original URL requ est
        print(response.response ?? "no response") // HTTP URL response
        print(response.data ?? "no data")     // server data
        print(response.result)   // result of response serialization
        print(response.response?.statusCode ?? "noCode")

        if(response.response?.statusCode != nil)
            switch response.response!.statusCode 
            case 200:
                print("Success")
                let json = JSON(data: response.data!)
                print(json)
                sender.onSuccessCall()
            case 400:
                print("Error in authentication")
            case 401:
                print("Error authentication object was not found")
            default:
                print("dEfault")
            
        
    

【讨论】:

【参考方案2】:

请试试这个代码

            let urlString = String(format : "Your URL" )


           let params: [String : Any] = [
                "profile": [
                    "Type": [
                    " Real Estate",
                    "Estater",
                    "Construction",
                    "Entertainment"
                    ],
                    "Size": [
                    "large",
                    "small"
                    ],
                    "Level": [
                    "A",
                    "B"
                    ],
                    "Name" : [
                    "John",
                    "Harry"
                    ]
                ]
            ]

            print(params)

            let url = URL(string: urlString)!



  let data = try! JSONSerialization.data(withJSONObject: params, options: JSONSerialization.WritingOptions.prettyPrinted)

    let json = NSString(data: data, encoding: String.Encoding.utf8.rawValue)
    if let json = json 
        print(json)
    

    let jsonData = json!.data(using: String.Encoding.utf8.rawValue);



           var request = URLRequest(url: url)
    request.httpMethod = HTTPMethod.post.rawValue
    request.setValue("application/json; charset=UTF-8", forHTTPHeaderField: "Content-Type")
    request.setValue("bearer e2ff3aa3-63a3-41d1-bc5a3e8c88adeaaa",forHTTPHeaderField: "Authorization")
            request.httpBody = jsonData

            Alamofire.request(request).responseJSON 
                (response) in

                switch response.result 
                case .success(let JSON):
                    print("Success with JSON: \(JSON)")



                    break

                case .failure(let error):
                    print("Request failed with error: \(error)")
                    //callback(response.result.value as? NSMutableDictionary,error as NSError?)
                    break
                


                
                .responseString  response in

                    print("Response String: \(response.result.value)")

            

【讨论】:

【参考方案3】:

有时我们需要 URLEncoding.httpBody 类型作为 post 方法希望它可以帮助你和

 let headers = [
                   // "Content-Type": "application/x-www-form-urlencoded" // try this if its ok then use this otherwise use  "application/json" 
                    // "Content-Type" : "application/json" 
                ]
            let parameters = [

                ]

            Alamofire.request("urlString", method: .post, parameters: parameters, encoding:  URLEncoding.httpBody, headers: headers).responseJSON  (response:DataResponse<Any>) in

                switch(response.result) 
                case.success(let data):
                    print("success",data)
               case.failure(let error):
                    print("Not Success",error)
                    self.view.makeToast(message: "Server Error!!")
                

            

【讨论】:

你把“Authorization”:“bearer e2ff3aa3-63a3-41d1-bc5a-3e8c88adeaaa”放在带有内容类型的标题中并尝试了这个 是的,我试过了,但是不行。我也试过这个代码 request.setValue("application/json", forHTTPHeaderField: "Content-Type" request.addValue("bearer e2ff3aa3-63a3-41d1-bc5a-3e8c88adeaaa", forHTTPHeaderField: "Authorization" 去 alamofire github 并尝试从他们更改 urlEncoding 类型,它们是关于 urlEncoding 的参考,有时我们的 urlEncoding 似乎不适用于 post 方法类型 让 params :Parameters = [ ] 在参数中尝试一次:[String : Any] 我认为它的问题在标头请求中。【参考方案4】:

使用URLConvertible在baseUrl中输入url

解决方法如下:

func file( sender: abc)

        let baseU = URL(string:"url")
        let baseUrl = baseU as! URLConvertible

        let params: [String : Any] = [
            "profile": [
                "Type": [
                " Real Estate",
                "Estater",
                "Construction",
                "Entertainment"
                ],
                "Size": [
                "large",
                "small"
                ],
                "Level": [
                "A",
                "B"
                ],
                "Name" : [
                "John",
                "Harry"
                ]
            ]
        ]

        let header = [
            "Authorization" : "bearer e2ff3aa3-63a3-41d1-bc5a-3e8c88adeaaa",
            "Content-Type" : "application/json"
        ]

        //        var request = URLRequest(url: URL(string:baseUrl)!)
        //        request.httpMethod = HTTPMethod.post.rawValue
        //        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        //        request.addValue("bearer e2ff3aa3-63a3-41d1-bc5a-3e8c88adeaaa", forHTTPHeaderField: "Authorization")
        //        let data = try! JSONSerialization.data(withJSONObject: params as Any, options:JSONSerialization.WritingOptions.prettyPrinted)
        //
        //        request.httpBody = data

        Alamofire.request(baseUrl, method: .post, parameters: params, headers:header).responseJSON  response in
            print(response.request ?? "no request")  // original URL requ est
            print(response.response ?? "no response") // HTTP URL response
            print(response.data ?? "no data")     // server data
            print(response.result)   // result of response serialization
            print(response.response?.statusCode ?? "noCode")

            if(response.response?.statusCode != nil)
                switch response.response!.statusCode 
                case 200:
                    print("Success")
                    let json = JSON(data: response.data!)
                    print(json)
                    sender.onSuccessCall()
                case 400:
                    print("Error in authentication")
                case 401:
                    print("Error authentication object was not found")
                default:
                    print("dEfault")
                
            
        

【讨论】:

谢谢,@Sakir Sherasiya。我试过了,但没用。 API 调用后。 我知道。我的意思是如果传递错误的 json 那么你就对了? 让我们continue this discussion in chat.

以上是关于如何在 Alamofire 中请求带有正文和标头的 JSON?的主要内容,如果未能解决你的问题,请参考以下文章

Alamofire POST 请求,正文中有一个简单的字符串作为参数,标头仍然显示缺少的参数值

带有标头的 Alamofire POST 请求

带有标头和原始 json 正文的 Volley POST 请求

401 alamofire 获取带有标头的请求

调试 Alamofire 请求

如何在 Alamofire 4.0 中仅使用参数和正文在 swift 中使用 POST 方法发送请求?