美文网首页网络
WKWebView对Cookie的处理

WKWebView对Cookie的处理

作者: 聪莞 | 来源:发表于2019-03-26 19:36 被阅读25次

    因为WKWebView是通过WebKit内核进行网络处理的,所以我们的NSHTTPCookieStorage里的Cookie是没办法拿到并带进一个请求的。可以通过下面的方法手动添加:

        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://www.baidu.com"]];
        NSArray *cookies = [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies;
        NSDictionary *requestHeaderFields = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
        //设置请求头
        request.allHTTPHeaderFields = requestHeaderFields;
    

    这种方式只对单个请求有效,一旦URL改变,Cookie还是会丢失,所以我们可以通过WKWebView的代理

    • (void)webView: decidePolicyForNavigationAction: decisionHandler:
      来对每一个request进行Cookie处理
    - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
        [[WKCookieManager shareManager] fixNewRequestCookieWithRequest:navigationAction.request];
        decisionHandler(WKNavigationActionPolicyAllow);
    }
    
    - (NSURLRequest *)fixNewRequestCookieWithRequest:(NSURLRequest *)originalRequest{
        NSMutableURLRequest *fixedRequest;
        if ([originalRequest isKindOfClass:[NSMutableURLRequest class]]) {
            fixedRequest = (NSMutableURLRequest *)originalRequest;
        } else {
            fixedRequest = originalRequest.mutableCopy;
        }
        //防止Cookie丢失
        NSDictionary *dict = [NSHTTPCookie requestHeaderFieldsWithCookies:[NSHTTPCookieStorage sharedHTTPCookieStorage].cookies];
        if (dict.count) {
            NSMutableDictionary *mDict = originalRequest.allHTTPHeaderFields.mutableCopy;
            [mDict setValuesForKeysWithDictionary:dict];
            fixedRequest.allHTTPHeaderFields = mDict;
        }
        return fixedRequest;
    }
    
    另外一种方式:

    可以在WKWebViewConfiguration的userContentController中注入脚本:

        WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
        WKUserContentController *controller = [[WKUserContentController alloc] init];
        [controller addUserScript:[[WKCookieManager shareManager] futhureCookieScript]];
        configuration.userContentController = controller;
    
    - (WKUserScript *)futhureCookieScript{
    // source 就是我们要调用的 JS 函数或者我们要执行的 JS 代码
    // injectionTime 这个参数我们需要指定一个时间,在什么时候把我们在这段 JS 注入到 WebVeiw 中,它是一个枚举值,WKUserScriptInjectionTimeAtDocumentStart 或者 WKUserScriptInjectionTimeAtDocumentEnd
    // MainFrameOnly 因为在 JS 中,一个页面可能有多个 frame,这个参数指定我们的 JS 代码是否只在 mainFrame 中生效
    - initWithSource:injectionTime:forMainFrameOnly:
        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 ?: @"/"];
        
        if (cookie.secure) {
            string = [string stringByAppendingString:@";secure=true"];
        }
    
            [script appendFormat:@"if (cookieNames.indexOf('%@') == -1) { document.cookie='%@'; };\n", cookie.name, string];
        }
        return script;
    }
    

    iOS11之后

    iOS11之后,有一个更简便的方法:

    /*! @abstract Returns the cookie store representing HTTP cookies in this website data store. */
    @property (nonatomic, readonly) WKHTTPCookieStore *httpCookieStore API_AVAILABLE(macosx(10.13), ios(11.0));
    
    //发送请求前插入cookie;
        NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
        WKHTTPCookieStore *cookieStore = [WKWebsiteDataStore defaultDataStore].httpCookieStore;
        
        if (cookies.count > 0) {
            for (NSHTTPCookie *cookie in cookies) {
                [cookieStore setCookie:cookie completionHandler:^{
                    
                }];
            }
        }
    
    

    相关文章

      网友评论

        本文标题:WKWebView对Cookie的处理

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