WKWebView关于Cookie的使用详解

引言

近期有个小应用大部分功能是用web页面实现的。为了提高交互体验,加载速度,所有页面都是WKWebView实现。前期实现直到上架测试,都是美滋滋的实现了。直到测试发现,某些情况下,web页面请求数据会返回登录过期,重新登录都不行。
后来发现是Cookie没有正确注入。之前webview系统会自动管理Cookie注入,WKWebView需要手动注入。如果网上能随便度娘到解决Cookie注入的方法,也不会写这篇文章了。写下这篇文章的目的,就是为了解救那些被Cookie虐的要放弃WKWebView的同伴。

使用

    WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init]
    configuration.userContentController = [[WKUserContentController alloc] init];
    configuration.allowsInlineMediaPlayback = YES;
    configuration.preferences.minimumFontSize = 10;
    configuration.processPool = [[WKProcessPool alloc]init];
    configuration.preferences.javaScriptCanOpenWindowsAutomatically = NO;
    // web内容处理池
    configuration.processPool = [[WKProcessPool alloc] init];
    // 将所有cookie以document.cookie = 'key=value';形式进行拼接
    NSString *cookieValue = @"document.cookie = 'fromapp=ios';document.cookie = 'channel=appstore';";
    // 加cookie给h5识别,表明在ios端打开该地址
    WKUserContentController* userContentController = WKUserContentController.new;
    WKUserScript * cookieScript = [[WKUserScript alloc]
                                       initWithSource: cookieValue
                                       injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
    [userContentController addUserScript:cookieScript];
    configuration.userContentController = userContentController;

    WKWebView *webView = [[WKWebView alloc] initWithFrame:frame configuration:configuration];
    webView.UIDelegate = self;
    webView.navigationDelegate = self;
    webView.allowsBackForwardNavigationGestures = YES;
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.urlString]];
    [request setValue:[self getCookieValue] forHTTPHeaderField:@"Cookie"];
    [webView loadRequest:request];

- (NSMutableString*)getCookieValue{
    // 在此处获取返回的cookie
    NSMutableDictionary *cookieDic = [NSMutableDictionary dictionary];
    NSMutableString *cookieValue = [NSMutableString stringWithFormat:@""];
    NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (NSHTTPCookie *cookie in [cookieJar cookies]) {
        [cookieDic setObject:cookie.value forKey:cookie.name];
    }
    // cookie重复,先放到字典进行去重,再进行拼接
    for (NSString *key in cookieDic) {
        NSString *appendString = [NSString stringWithFormat:@"%@=%@;", key, [cookieDic valueForKey:key]];
        [cookieValue appendString:appendString];
    }
    return cookieValue;
}

防止Cookie为空,代理方法中再次注入

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler
{  
    BOOL isNavigator = YES;

    NSDictionary *headerFields = request.allHTTPHeaderFields;
    NSString *cookie = headerFields[@"Cookie"];
    if (cookie == nil) {
        NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:request.URL];
        urlRequest.allHTTPHeaderFields = headerFields;
        [urlRequest setValue:[self getCookieValue] forHTTPHeaderField:@"Cookie"];
        [webView loadRequest:request];
        isNavigator = NO;
    }else{
        isNavigator = YES;
    }

    if (!isNavigator) {
        decisionHandler(WKNavigationActionPolicyCancel);
    }else{
        decisionHandler(WKNavigationActionPolicyAllow);
    }
}

你可能感兴趣的:(iOS开发,移动端+大前端+后台学习整合)