iOS 在WKWebView设置多个Cookie(总结我跑过的坑)
不废话,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);
}];
}