如何使用Alamofire读取响应cookie

20

我正在尝试读取一个Post请求的响应cookies,就像Postman下面展示的那样。

在这里输入图片描述

而我现在尝试的方式一直没有成功。

    var cfg = NSURLSessionConfiguration.defaultSessionConfiguration()
    var cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage()
    cfg.HTTPCookieStorage = cookies
    cfg.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicy.Always

    var mgr = Alamofire.Manager(configuration: cfg)


    mgr.request(.POST, "http://example.com/LoginLocalClient", parameters: parameters).responseJSON { response in

                print(response.response!.allHeaderFields)

                print(NSHTTPCookieStorage.sharedHTTPCookieStorage().cookies)
}

第一个打印语句包含10个标题字段但不包括cookie,第二个打印语句包含一个空数组。

有什么想法吗?


你解决过这个问题吗?Alamofire的github上,也不是这里接受的答案能解决这个问题。我正在使用一个第三方API,他们在会话中使用了cookie -- 但是我不知道如何获取它们。 - JRam13
请查看 https://dev59.com/11sX5IYBdhLWcg3wS9_o#41881600 获取正确的答案。 - JRam13
5个回答

31
你需要使用 NSHTTPCookiecookiesWithResponseHeaderFields(_:forURL:) 方法从响应中提取 cookies。这是一个快速示例:
func fetchTheCookies() {
    let parameters: [String: AnyObject] = [:]

    Alamofire.request(.POST, "http://example.com/LoginLocalClient", parameters: parameters).responseJSON { response in
        if let
            headerFields = response.response?.allHeaderFields as? [String: String],
            URL = response.request?.URL
        {
            let cookies = NSHTTPCookie.cookiesWithResponseHeaderFields(headerFields, forURL: URL)
            print(cookies)
        }
    }
}

Swift 5

func fetchTheCookies() {
    let parameters: [String: AnyObject] = [:]

    Alamofire.request(.POST, "http://example.com/LoginLocalClient", parameters: parameters).responseJSON { response in
        if let headerFields = response.response?.allHeaderFields as? [String: String], let URL = response.request?.url
        {
             let cookies = HTTPCookie.cookies(withResponseHeaderFields: headerFields, for: URL)
             print(cookies)
        }
    }
}

您试图进行的所有配置自定义都不会产生任何影响。您设置的值已经是默认值了。


3
很遗憾,它对我没有用 :( 还打印了空字段。 - Tj3n
3
你解决了吗?Cookies 一直是空的。除了 Set-Cookie,我的所有标头都在那里,但 Android 可以看到 Set-Cookie 标头... - datWooWoo
@cnoon 我也遇到同样的问题,使用了上面的代码但是在 cookie 中没有获取到任何元素,不知道能否请您帮忙解决。 - Daljeet
为什么这个答案被接受了?就像其他人所表达的那样,这并没有解决问题。Cookie 总是空白。 - JRam13
请查看 https://dev59.com/11sX5IYBdhLWcg3wS9_o#41881600 获取正确答案。 - JRam13

25

请注意,如果cookie未在标头响应中发布,则所接受的答案无效。显然,一些cookie会被提前提取并存储在共享cookie存储中,并不会随响应一起出现

你必须使用 HTTPCookieStorage.shared.cookies

Swift 3:

        Alamofire.request(url, method: HTTPMethod.post, parameters: parameters).responseData { (responseObject) -> Void in

            if let responseStatus = responseObject.response?.statusCode {
                if responseStatus != 200 {
                    // error
                } else {
                    // view all cookies
                    print(HTTPCookieStorage.shared.cookies!)
                }
            }
        }

感谢Travis M


5

如果你只想读取与你正在交互的域名相关的所有cookie,可以使用此方法获取所有cookie。

let cookies = Alamofire.Manager.sharedInstance.session.configuration.HTTPCookieStorage?.cookiesForURL(NSURL(string: "mydomain.com")! )

它返回一个可选的NSHTTPCookie数组。 (Swift 2.2和Alamofire 3.4)

Swift 4.1:

let cookies = Alamofire.SessionManager.default.session.configuration.httpCookieStorage?.cookies(for: url)

3
上述代码是正确的,我已经按照以下方式使用 -
 var allCookies: [NSHTTPCookie]?
        if let headerFields = aResponse.response?.allHeaderFields as? [String: String],
            URL = aResponse.request?.URL {
            allCookies = NSHTTPCookie.cookiesWithResponseHeaderFields(headerFields, forURL: URL)
            for cookie in allCookies! {
                print(cookie)
                let name = cookie.name
                if name == "nmSession" {
                    let value = cookie.value
                    print(value)
                }
            }

        }

1

@lespommes

这是我收到Cookie的唯一方式。现在我终于可以在响应中看到Set-Cookie了:

    let parameters =  ["postLogin": ["login": "mymail@gmail.com", "password": "myPassword"]]

    let url = NSURL(string: "your-website-with-cookies.com")

    let request = NSMutableURLRequest(URL: url!)
    request.HTTPMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Accept")
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")

    request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(parameters, options: [])

    Alamofire.request(request)
        .responseJSON { response in

            debugPrint(response)

            if response.result.isSuccess {
                ...
                }
            }else if (response.result.isFailure){
                ...
            }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接