iOS 在WKWebView设置多个Cookie(总结我跑过的坑)

时间:2024-03-28 22:38:01

不废话,1-直接说坑;2-po代码。

1-直接说坑

重点1: 通过字典设置相关参数,生成NSHTTPCOOKie对象。我这里生成了三个。并装填进数组中。并给request的HTTPHeaderField进行keyValue赋值。

重点2: 初始化webView时,要进行对javaScript进行注入。所有的cookie拼接成一个字符串。用分号和换行符隔开。(保证在首次load前,cookie中的数据已存入。)

重点3: 每次进行重定向,也就是调用WKWebView如下代理方法时。都要获取Cookie,并再次传入。保证每次loadURL,都能获取到Cookie

-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler

重点4: cookie中如果要传嵌套对象。比如一个包含多个字典的数组,则需要通过NSData 中转,转换为字符串。存入cookieValue中。

重点5:iOS中的cookie不能有中文,需要encode后传入,相应的,如果JS端不能识别,则需要decode。保证安卓和iOS都能存入cookie。这里主要是前端人员的事务。需要沟通。

2-po代码

初始化WKWebView

-(WKWebView*)webV{
    if (_webV==nil) {
        WKWebViewConfiguration*configuration=[[WKWebViewConfiguration alloc]init];
        // 设置偏好设置
        configuration.preferences = [[WKPreferences alloc] init];
        configuration.preferences.minimumFontSize = 10;
        configuration.preferences.javaScriptCanOpenWindowsAutomatically = NO;
        // 默认认为YES
        configuration.preferences.javaScriptEnabled = YES;
        configuration.userContentController = [[WKUserContentController alloc] init];
        configuration.allowsInlineMediaPlayback = YES;
        
        configuration.processPool = [[WKProcessPool alloc]init];
        
        // web内容处理池
        configuration.processPool = [[WKProcessPool alloc] init];
 
//        LHX20181206 设定UserKey_cookie
        NSDictionary *dictCookie_userKey = [NSDictionary dictionaryWithObjectsAndKeys:@"user_key", NSHTTPCookieName,
                                          _dlModel.user_key, NSHTTPCookieValue,
                                          @"/", NSHTTPCookiePath,
                                          self.uustr, NSHTTPCookieDomain,nil];
        
        NSHTTPCookie *cookieUserKey = [NSHTTPCookie cookieWithProperties:dictCookie_userKey];
//        LHX20181206 设定UserKey_cookie
        NSDictionary *dictCookie_loToken = [NSDictionary dictionaryWithObjectsAndKeys:@"loToken", NSHTTPCookieName,
                                          _dlModel.loToken, NSHTTPCookieValue,
                                          @"/", NSHTTPCookiePath,
                                          self.uustr, NSHTTPCookieDomain,nil];

        NSHTTPCookie *cookieLoToken = [NSHTTPCookie cookieWithProperties:dictCookie_loToken];
        
//        LHX20181206 设定UserKey_cookie
        NSDictionary *dictCookie_ModulePerm = [NSDictionary dictionaryWithObjectsAndKeys:@"module_perm", NSHTTPCookieName,
                                             [self changeDicArrayToString: _dlModel.modulePerm] , NSHTTPCookieValue,
                                             @"/", NSHTTPCookiePath,
                                             self.uustr, NSHTTPCookieDomain,nil];
        
        NSHTTPCookie *cookieModulePerm = [NSHTTPCookie cookieWithProperties:dictCookie_ModulePerm];
        
        NSArray *arrCookies = [NSArray arrayWithObjects: cookieUserKey, cookieLoToken,cookieModulePerm, nil];
        NSDictionary *dictCookies = [NSHTTPCookie requestHeaderFieldsWithCookies:arrCookies];//将cookie设置到头中
        
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[self.urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] ]];


        [request setValue: [dictCookies objectForKey:@"Cookie"] forHTTPHeaderField: @"Cookie"];
//
        WKUserContentController* userContentController = WKUserContentController.new;
        
//这里注入cookie。所有的cookie拼接成一个字符串。用分号和换行符隔开,如下:
        self.cookieStr=@"".mutableCopy;
        if (self.cookieArray) {
            for (NSHTTPCookie*cookie in self.cookieArray) {
                [self.cookieStr appendFormat:@"document.cookie = '%@=%@';\n",cookie.name,cookie.value];
            }
        }
        
        WKUserScript * cookieScript = [[WKUserScript alloc] initWithSource: self.cookieStr injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
        [userContentController addUserScript:cookieScript];
       
        configuration.userContentController = userContentController;
        
        _webV= [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH,SCREEN_HEIGHT) configuration:configuration];
        if (@available(iOS 11.0, *)) {
            self.webV.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        } else {
            self.edgesForExtendedLayout = UIRectEdgeNone;
        }
        if (@available(iOS 11.0, *)) {
            WKHTTPCookieStore *cookieStore = _webV.configuration.websiteDataStore.httpCookieStore;
            for (NSHTTPCookie*cookie in self.cookieArray) {
                 [cookieStore setCookie:cookie completionHandler:nil];
            }
           
        }
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:self.cookieArray forURL:[NSURL URLWithString:[self.urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding] ] mainDocumentURL:nil];
        NSLog(@"LHXNSHTTPCookieStorage%@",[self getCookieValue] );
        _webV.UIDelegate = self;
        _webV.navigationDelegate = self;
        _webV.allowsBackForwardNavigationGestures = YES;

        [_webV loadRequest:request];


    }

    return _webV;
}

嵌套对象转为纯字符串

-(NSString*)changeDicArrayToString:(NSArray<NSDictionary*>*)array{
    
    NSMutableArray*mutiArray=@[].mutableCopy;
    for (NSDictionary*dic in array) {
        NSMutableDictionary*mutiDic=[NSMutableDictionary dictionaryWithDictionary:dic];
        mutiDic[@"name"]=[mutiDic[@"name"] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
        [mutiArray addObject:mutiDic];
    }
    
    NSData*data=[NSJSONSerialization dataWithJSONObject:mutiArray options:NSJSONWritingPrettyPrinted error:nil];
    NSString*jsonStr=[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
    NSMutableString *mutStr = [NSMutableString stringWithString:jsonStr];
    NSRange range = {0,jsonStr.length};
    //去掉字符串中的空格
    [mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
    NSRange range2 = {0,mutStr.length};
    //去掉字符串中的换行符
    [mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
    

    return mutStr;

    
}

重定向时,重新注入,防止cookie被抹掉


-(void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler{
    NSLog(@"%s/n",__FUNCTION__);
    
    if (_timer!=nil) {
        [_timer invalidate];
        _timer=nil;
    }

    _timer=[NSTimer timerWithTimeInterval:30*60 repeats:NO block:^(NSTimer * _Nonnull timer) {
        [self handleCustomAction:@""];
        return ;
        
    }];
 
    NSString*str=[navigationAction.request.URL.absoluteString stringByRemovingPercentEncoding];
    if ([str hasSuffix:@"/login"]) {
        // 拦截点击链接
        [self handleCustomAction:str];
        // 不允许跳转
        decisionHandler(WKNavigationActionPolicyCancel);
        return;
    }
    
//    BOOL isNavigator = YES;
//    LHX20181213,再次添加cookie保证每次跳转页面,都能获取到此cookie。三个参数
    [webView evaluateJavaScript:self.cookieStr completionHandler:^(id result, NSError *error) {
        NSLog(@"cookie-------%@",result);
         decisionHandler(WKNavigationActionPolicyAllow);
    }];



}

我是大马猴,希望大家指教切磋###

iOS 在WKWebView设置多个Cookie(总结我跑过的坑)