WKWebView的cookie一个神坑

一般使用WKWebView的时候,我们需要手动注入cookie:

[_webView evaluateJavaScript:@"document.cookie=....." completionHandler:nil];

常见的,cookie总是由登录接口获取,保存在NSHTTPCookieStorage,当我们需要手动注入的时候,往往通过cookie.name来过滤获取:

NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];

for (NSHTTPCookie *cookie in [cookieStorage cookies]) {
    if ([cookie.name isEqualToString:@"UUID"]) {
          // 使用document.cookie=方式注入指定的cookie
          NSString *nameStr = [NSString stringWithFormat:@"document.cookie='%@=\"%@\";expires=Wed, 25 Sep 2075 17:05:15 GMT;domain=%@;path=%@;verson=%lu;'",cookie.name,cookie.value, @".baidu.com", cookie.path, (unsigned long) cookie.version];
         [self.myWebView evaluateJavaScript:nameStr completionHandler:nil];
    }
}

以上的代码,请注意,我们使用双引号包裹了cookie.value。这在一般情况下是没有问题的。然而,它可能在某些情况下导致服务端获取的cookie多了很多层双引号!

这是为什么呢?

通过调试,发现NSHTTPCookieStorage中的部分cookie,会自动同步到webView.configuration.websiteDataStore.httpCookieStore中。并且,如果通过document.cookie=的方式给WebView注入cookie,最终也会自动保存到webView.configuration.websiteDataStore.httpCookieStoreNSHTTPCookieStorage中。

目前,我个人调试后发现的规律是:

  1. 当webView初次加载的时候,会自动将NSHTTPCookieStorage中的cookie值拷贝到webView.configuration.websiteDataStore.httpCookieStore中;
  2. webView加载的时候,document.cookie中的值,是通过webView.configuration.websiteDataStore.httpCookieStore来赋值的;
  3. 如果你手动调用了document.cookie=,则会将该cookie值自动保存到WKHTTPCookieStorageNSHTTPCookieStorage中(先后顺序现在还没法搞清楚)。

那么根据以上流程,如果使用双引号包裹了cookie.value,会导致设置了document.cookie后,自动更新WKHTTPCookieStorageNSHTTPCookieStorage,导致它们两个中的值也带上了双引号。然后下次注入的时候,我们的代码从NSHTTPCookieStorage中取出cookie,又添加了一次双引号..... 如此重复,导致服务端或H5最终无法解析。

根据我们这边H5和服务端的反馈,cookie值没有双引号,或者有一对双引号都是没有问题的,再多就解析不出来了。

大家在注入cookie的时候,最好还是不要手动追加任何格式的好。

另外必须提出的是,我在模拟器上测试了很多遍,然而document.cookie=的方式注入,并不会写回到NSHTTPCookieStorage中(WKHTTPCookieStorage还是可以写回的),然而更换到真机,这个问题是100%复现!!!

建议大家调试webView的时候,还是用真机的好。

你可能感兴趣的:(WKWebView的cookie一个神坑)