从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数据?
最后, httpCookieStore
的WKWebsiteDataStore
在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:为:)