美文网首页iOS开发iOS开发技巧
iOS WKWebView同步Cookies问题

iOS WKWebView同步Cookies问题

作者: 淡定的笨鸟 | 来源:发表于2019-05-17 00:32 被阅读0次

    之前在项目中使用WKWebView加载web网页时,出现Cookies在App端不同步的问题,在UIWebView中却是好用的,以为是WKWebView的坑,就通过JS交互的方式解决的,实际上这样并不好,这样做不但即时性不好,而且还浪费带宽,现在找到原因了,在此记录一下加深记忆。

    这是Demo

    更新-发现个问题:如果使用模拟器测试的话需要配合Charles软件测试,不然不准。

    WKWebView使用的内核和UIWebView不同,在使用UIWebView时,在沙盒目录下会生成一个Library/Cookies文件夹。


    UIWebView的沙盒目录

    文件夹下就是保存的Cookies,在Library/preference中也有一个plist文件,从中也可以看到保存的Cookies


    Preference中的Cookies.plist
    而WKWebView则会在Library文件夹下生成一个WebKit文件夹,这里面都是只能看到文件夹,看不到Cookies,所以我们需要在平时使用WKWebView时做一些处理,通常有三种方式。
    拼接Cookies的方式(常用)

    原来的WKWebView加载url时是这样的

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [self.wkWebView loadRequest:request];
    

    现在做出修改如下:

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
    NSDictionary *dict = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
    request.allHTTPHeaderFields = dict;
    [self.wkWebView loadRequest:request];
    

    因为WKWebView的Cookies是WebKit的,和NSHTTPCookieStorage不是同步的,所以我们在加载网页的时候要拼接上去。
    同样为了解决跨域问题,在代理中每次跳转之前拼接Cookies

    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
        NSURL *url = navigationAction.request.URL;
        [self wkWebViewWillStart:url];
        //为了解决跨域问题,每次跳转url时把cookies拼接上
        NSMutableURLRequest *request = (NSMutableURLRequest *)navigationAction.request;
        NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
        NSDictionary *dict = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
        request.allHTTPHeaderFields = dict;
        
        decisionHandler(WKNavigationActionPolicyAllow);
    }
    
    注入JS代码的方式
    //通过注入JS解决Cookies不同步的问题
    - (WKUserScript *)injectCookieScript{
        WKUserScript * cookieScript = [[WKUserScript alloc] initWithSource:[self cookieString] injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
        return cookieScript;
    }
    
    - (NSString *)cookieString
    {
        NSMutableString *script = [NSMutableString string];
        [script appendString:@"var cookieNames = document.cookie.split('; ').map(function(cookie) { return cookie.split('=')[0] } );\n"];
        for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
            
            if ([cookie.value rangeOfString:@"'"].location != NSNotFound) {
                continue;
            }
            
            NSString *string = [NSString stringWithFormat:@"%@=%@;domain=%@;path=%@",
                                cookie.name,
                                cookie.value,
                                cookie.domain,
                                cookie.path ?: @"/"];
            
            [script appendFormat:@"if (cookieNames.indexOf('%@') == -1) { document.cookie='%@'; };\n", cookie.name, string];
        }
        return script;
    }
    

    这种就是通过document.cookie同步到NSHTTPCookieStorage,简单方便。

    WKWebsiteDataStore

    在WKWebView中设置下面这句就可以了,他可以同步NSHTTPCookieStorage和WKWebView的Cookies,但是目前只支持iOS11.0以上的系统。

    [WKWebsiteDataStore defaultDataStore].httpCookieStore;
    

    以上就是WKWebView解决Cookies与NSHTTPCookieStorage不同步的问题。
    Demo

    相关文章

      网友评论

        本文标题:iOS WKWebView同步Cookies问题

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