WKWebView,获取所有的cookies

9
我希望获取WKWebView中的所有cookie。为什么?我正在启动一个使用基于Web的身份验证的项目。因此,我需要拦截cookie以确保用户已登录并用于其他一些目的。另一种情况是,想象一下用户已登录,然后他“杀死”应用程序 - 由于存储此cookie会话的某些延迟,会话将丢失 :(。

问题似乎在于cookie被缓存而不立即保存到文件中。

(@Kemenaran from here - p.5 below)

我尝试捕获它们的地方是 -

webView:decidePolicyForNavigationResponse:decisionHandler:

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 {
            NSHTTPCookieStorage.shared.set(cookie)
      }
    }
  }
}

但并非所有请求都是导航请求,因此有一个cookie(在我的情况下)被跳过了,请参见下面的详细信息。

enter image description here

关于我尝试过的其他选项...

  1. 是的,我知道从iOS 11开始,我们可以像这里提到的那样使用WKHTTPCookieStore。但我的项目应支持iOS 9+。

enter image description here


  1. 我可以百分之百确定,在登录后的5-10秒内,所需的cookie将被保存到NSHttpCookieStorage中(至少在过去几天的所有测试中都是如此)。

  2. 我尝试使用提供的观察者NSHTTPCookieManagerCookiesChangedNotification,但它只为在webView:decidePolicyForNavigationResponse:decisionHandler中出现的cookie提供回调。

  3. 我还尝试使用一些JS来获取cookie,例如这里提到的,以及这里中提到的所有建议-顺便说一句,这是一篇真正棒的文章。结果-否定的。

  4. 我还发现了这个radar bug,以及这个SO questionSample project,但我想要避免甚至这种情况。(本文所述的情况不仅适用于删除,还适用于保存)当用户杀死应用程序时,这种情况也是正确的,因此可能存在用户登录、杀死应用程序并重新启动的情况。防止这种情况(仅通过检查所需cookie的NSHttpCookieStorage也不是一个好主意,因为在登录后,所需的cookie可能会有一些延迟存储,因此这种方法需要一些布尔值解决方案,看起来很奇怪...)

  5. 我还阅读了几篇与某些相关问题有关的SO文章,其中最有用的是:

但仍然没有好的解决方案...

那么,是否存在任何方法来获取或至少强制立即存储cookie?

1个回答

2

我最终采用了简单的“强制保存”方式从网页上保存Cookie。

我使用带有JS字符串的stringByEvaluatingJavaScriptFromString来获取所有Cookie,例如document.cookie();。结果,我能够将所有cookie作为一个带有;分隔符的字符串接收。我所需要做的就是解析字符串、创建cookie并将其设置到NSHttpSharedStorage中。


1
这种方法的问题在于您将无法读取httponly cookies。 - Ajith
NSDictionary *eventInitDict = @{ @"data": message, }; NSString *source = [NSString stringWithFormat:@"document.dispatchEvent(new MessageEvent('message', %@));", RCTJSONStringify(eventInitDict, NULL) ]; [_webView stringByEvaluatingJavaScriptFromString:source]; - hbk
something like this - hbk

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