从WKWebView获取所有的cookies

虽然通过使用NSHTTPCookieStorage.sharedHTTPCookieStorage()UIWebView获取cookie似乎很简单,但似乎WKWebView将cookie存储在其他地方。

我做了一些研究,并从NSHTTPURLResponse对象中获取了一些cookie。 但是,这并不包含WKWebView使用的所有Cookie:

 func webView(webView: WKWebView, decidePolicyForNavigationResponse navigationResponse: WKNavigationResponse, decisionHandler: (WKNavigationResponsePolicy) -> Void) { if let httpResponse = navigationResponse.response as? NSHTTPURLResponse { if let headers = httpResponse.allHeaderFields as? [String: String], url = httpResponse.URL { let cookies = NSHTTPCookie.cookiesWithResponseHeaderFields(headers, forURL: url) for cookie in cookies { logDebug(cookie.description) logDebug("found cookie " + cookie.name + " " + cookie.value) } } } } 

奇怪的是,在iOS 9中还有一个类WKWebsiteDataStore负责pipe理WKWebView cookie,但是该类不包含公共方法来检索cookie数据:

 let storage = WKWebsiteDataStore.defaultDataStore() storage.fetchDataRecordsOfTypes([WKWebsiteDataTypeCookies], completionHandler: { (records) -> Void in for record in records { logDebug("cookie record is " + record.debugDescription) for dataType in record.dataTypes { logDebug("data type is " + dataType.debugDescription) // get cookie data?? } } 

有没有解决方法来获取cookie数据?

最后, httpCookieStoreWKWebsiteDataStore在iOS 11中登陆。

https://developer.apple.com/documentation/webkit/wkwebsitedatastore?changes=latest_minor

WKWebView使用(创build)的WKWebView实际上正确存储在NSHTTPCookieStorage.sharedHTTPCookieStorage()

问题是WKWebView不会立即写回cookie。 我认为这是按照自己的时间表。 例如,当一个WKWebView被closures或者可能是周期性的。

所以最终他们最终在那里,但是什么时候是不可预测的。

您可以通过closures您的WKWebView来强制“共享” WKWebView 。 请让我们知道这是否工作。

更新 :我只记得,在iOS版的Firefox中,我们强制WKWebView通过replace它的WKWebView来刷新其内部数据,包括cookie。 没有官方的API,但我很确定这是目前最可靠的解决方法。

正如Stefan所说,cookie存储在NSHTTPCookieStorage.sharedHTTPCookieStorage()

但是,从我的实验中,我发现服务器设置的会话cookie对于NSHTTPCookieStorage.sharedHTTPCookieStorage()是不可见的。

只要每个WKWebView共享同一个WKWebView实例, WKProcessPool这些会话Cookie将会被传回给服务器,以用于每个请求。 如果您更改WKWebView的进程池,则实际上将删除所有未来请求的会话Cookie。

在实践中,我发现在“decidePolicyForNavigationResponse”的方法中,可以使用下面的方法来获取cookie,但可悲的是它不是一个完整/整个会话列表。

 let response = navigationResponse.response as! NSHTTPURLResponse let headFields = response.allHeaderFields as! [String:String] let cookies = NSHTTPCookie.cookiesWithResponseHeaderFields(headFields, forURL: response.URL!) 

这篇文章有关于使用WKWebView进行cookie处理的有用信息。 据此,你应该可以使用标准的NSURLCache和NSHTTPCookie来设置和检索cookie。 他还提到按照Stephan的评论使用WKProccessPool。

NSHTTPCookie.cookiesWithResponseHeaderFields(headers, forURL: url) ,如果Cookie设置的url不是导航响应url(导致导航的url),会发生什么? 我注意到cookies设置的callbackurl在决定政策导航响应中从来不会被调用。

 func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse, decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) { let response = navigationResponse.response as! HTTPURLResponse let cookies = HTTPCookie.cookies(withResponseHeaderFields: response.allHeaderFields as! [String : String], for: response.url!) } 

上面的委托永远不会执行callbackurl,因为callback本身不会导致页面导航。

cookies(withResponseHeaderFields:为:)