WKWebView 设置 Cookie
在 Apple 推出 WKWebView 之后,大家都知道 WKWebView 比 UIWebView 更加优秀,WKWebView 确实是优秀,但是也存在一些问题,比如被人诟病的 cookie 设置问题。
在使用 UIWebView 的时候,我们是通过 NSHTTPCookieStorage 来管理 cookie 的,我们给 mobi.domain.com 域名添加一个名字为 auth 的 cookie,代码类似下面。
NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
[cookieProperties setObject:@"auth" forKey:NSHTTPCookieName];
[cookieProperties setObject:@"xxxxxx" forKey:NSHTTPCookieValue];
[cookieProperties setObject:@"mobi.domain.com" forKey:NSHTTPCookieDomain];
[cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
在 WKWebView 中通过 NSHTTPCookieStorage 来设置 cookie 是行不通的,要通过 URLRequest 来添加 cookie 才能起效果 。代码类似下面。
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://mobi.domain.com"]];
NSDictionary *headFields = request.allHTTPHeaderFields;
NSString * cookie = headFields[@"auth"];
if (cookie == nil) {
[request addValue:[NSString stringWithFormat:@"auth=%@", @"authValue"] forHTTPHeaderField:@"Cookie"];
}
[self.webView loadRequest:request];
你以为 WKWebView 添加 cookie 就这样结束了 ? 其实远远没有。上面通过 URLRequest 来添加 cookie 的方式只能对 WKWebView loadRequest 的那个 request 起作用,如果你的 WKWebView 加载的 Web 页面包含了 ajax 请求的话,那 cookie 又要重新处理了,这个处理需要在 WKWebView 的 WKWebViewConfiguration 中进行配置。代码类似下面。
//应用于 ajax 请求的 cookie 设置
WKUserContentController *userContentController = WKUserContentController.new;
NSString *cookieSource = [NSString stringWithFormat:@"document.cookie = 'auth=%@';", @"authValue"];
WKUserScript *cookieScript = [[WKUserScript alloc] initWithSource:cookieSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
[userContentController addUserScript:cookieScript];
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.userContentController = userContentController;
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"http://mobi.domain.com"]];
// 应用于 request 的 cookie 设置
NSDictionary *headFields = request.allHTTPHeaderFields;
NSString * cookie = headFields[@"auth"];
if (cookie == nil) {
[request addValue:[NSString stringWithFormat:@"auth=%@", @"authValue"] forHTTPHeaderField:@"Cookie"];
}
self.webView = [[WKWebView alloc] initWithFrame:self.view.frame configuration:config];
[self.webView loadRequest:request];
到这里是不是结束了呢?其实还是没有,从这篇文章 《 WKWebView 那些坑》(https://mp.weixin.qq.com/s/rhYKLIbXOsUJC_n6dt9UfA)中可以看到 “ document.cookie()无法跨域设置 cookie ”,显然如果你的 WKWebView 页面没有跨域问题的话,那么通过以上的方式是可以解决 WKWebView 设置 cookie 的问题。
到最后献上苹果工程师在官方论坛的一个关于 WKWebView Cookie 问题的答复 (https://forums.developer.apple.com/thread/77279),该答复大意是说,如果要保证 cookie 正常工作,那么就不要使用 WKWebView,而是使用 UIWebView 。如果你在考虑是否从 UIWebView 迁移到 WKWebView 的话,建议你先看看 《 WKWebView 那些坑》(https://mp.weixin.qq.com/s/rhYKLIbXOsUJC_n6dt9UfA),如果你的业务无法规避或者处理里面提到的一些 WKWebView 巨坑,那么我认为 WKWebView 对你来说并不是一个更好的选择。