一般使用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.httpCookieStore
和NSHTTPCookieStorage
中。
目前,我个人调试后发现的规律是:
- 当webView初次加载的时候,会自动将
NSHTTPCookieStorage
中的cookie值拷贝到webView.configuration.websiteDataStore.httpCookieStore
中; - webView加载的时候,
document.cookie
中的值,是通过webView.configuration.websiteDataStore.httpCookieStore
来赋值的; - 如果你手动调用了
document.cookie=
,则会将该cookie值自动保存到WKHTTPCookieStorage
和NSHTTPCookieStorage
中(先后顺序现在还没法搞清楚)。
那么根据以上流程,如果使用双引号包裹了cookie.value
,会导致设置了document.cookie
后,自动更新WKHTTPCookieStorage
和NSHTTPCookieStorage
,导致它们两个中的值也带上了双引号。然后下次注入的时候,我们的代码从NSHTTPCookieStorage
中取出cookie,又添加了一次双引号..... 如此重复,导致服务端或H5最终无法解析。
根据我们这边H5和服务端的反馈,cookie值没有双引号,或者有一对双引号都是没有问题的,再多就解析不出来了。
大家在注入cookie的时候,最好还是不要手动追加任何格式的好。
另外必须提出的是,我在模拟器上测试了很多遍,然而document.cookie=
的方式注入,并不会写回到NSHTTPCookieStorage
中(WKHTTPCookieStorage
还是可以写回的),然而更换到真机,这个问题是100%复现!!!
建议大家调试webView的时候,还是用真机的好。
网友评论