使用 Alamofire 调用带有 HTTP Header 和 Body 的 API

Posted

技术标签:

【中文标题】使用 Alamofire 调用带有 HTTP Header 和 Body 的 API【英文标题】:Calling an API with HTTP Header and Body with Alamofire 【发布时间】:2016-12-13 22:15:55 【问题描述】:

我正在尝试使用 Alamofire 4 重新创建已经在 Swift 3 中的 Postman 中工作的 POST 请求,但我总是收到状态代码 400“错误请求”。我不知道我在这里做错了什么。

这是 Postman 中的请求,另外还有 JSON 格式的 Body 中的用户名和密码:

阅读 Alamofire 的文档,我认为这应该是正确的 Swift 代码:

func login(as username: String, withPassword password: String) 

    let url = "https://api2.drive-now.com/login"

    let parameters: Parameters = [
        "username" : username,
        "password" : password
    ]

    let loginHeaders: HTTPHeaders = [
        "Accept" : "application/json;v=1.6",
        "Accept-Encoding" : "gzip, deflate, sdch",
        "Accept-Language" : "de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4",
        "Connection" : "keep-alive",
        "Host" : "api2.drive-now.com",
        "Origin" : "https://de.drive-now.com",
        "X-Api-Key" : "adf51226795afbc4e7575ccc124face7",
        "X-Language" : "de",
        "Content-Type" : "application/json"
    ]

    Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: loginHeaders).responseJSON  response in
        print("Request: \(response.request)")    // original URL request
        print("Response: \(response.response)")  // HTTP URL response
        print("Data: \(response.data)")          // server data
        print("Result: \(response.result)")      // result of response serialization

        if let JSON = response.result.value 
            print("JSON: \(JSON)")
        
    


我的控制台输出是:

Request: Optional(https://api2.drive-now.com/login)
Response: Optional(<NSHTTPURLResponse: 0x6000000266a0>  URL: https://api2.drive-now.com/login   status code: 400, headers 
Connection = close;
"Content-Length" = 181;
"Content-Type" = "text/html";
Date = "Tue, 13 Dec 2016 22:12:46 GMT";
Server = "nginx/1.4.6 (Ubuntu)";
 )
Data: Optional(181 bytes)
Result: FAILURE

是否有我必须实施的自定义会话管理器?或者你知道我可以在这里使用的任何调试方法吗?

【问题讨论】:

【参考方案1】:

一位熟悉 API 的朋友确实帮我解决了这个问题:它是一个默认的标头字段,似乎是 Alamofire 添加到每个调用中的。 API 不接受带有“User-Agent”集的调用(不要问我为什么)。

为了帮助可能遇到相同问题的其他人,我分享了我为查找和解决问题所经历的步骤:

    我将Alamofire.request(...) 变成了一个名为postage 的变量(当然,你可以随意调用它) 我在login-函数的末尾添加了debugPrint(postage) 输出显示了额外的标头字段

    我构建了一个自定义的 SessionManager,如下所示

    var headers = Alamofire.SessionManager.defaultHTTPHeaders
    headers.removeValue(forKey: "User-Agent")
    
    let configuration = URLSessionConfiguration.default
    configuration.httpAdditionalHeaders = headers
    
    api = Alamofire.SessionManager(configuration: configuration)
    

【讨论】:

以上是关于使用 Alamofire 调用带有 HTTP Header 和 Body 的 API的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Alamofire 发送带有压缩内容的 HTTP POST 请求?

发送带有参数的 Alamofire 请求以及 HTTP 正文中的图像

带有嵌套参数的 Alamofire POST 请求不返回任何内容

使用 alamofire 发布带有字典和字典数组的 JSON 对象

带有标头的 Alamofire 请求?

alamofire:带有标头的 POST 请求