WKWebView 设置 Cookie

作者: 要上班的斌哥 | 来源:发表于2017-11-27 00:25 被阅读447次

    在 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 对你来说并不是一个更好的选择。

    参考

    1. https://mp.weixin.qq.com/s/rhYKLIbXOsUJC_n6dt9UfA
    2. https://forums.developer.apple.com/thread/77279
    3. https://stackoverflow.com/questions/26573137/can-i-set-the-cookies-to-be-used-by-a-wkwebview/26577303#26577303

    相关文章

      网友评论

        本文标题:WKWebView 设置 Cookie

        本文链接:https://www.haomeiwen.com/subject/xifzvxtx.html