之前做项目的时候服务器那边使用cookie来判断用户登录状态的,让后用H5页面的时候需要传入cookie,但是wkwebview又不支持直接使用NSHTTPCookieStorage里面的Cookie,按照网上写的接入都有点问题,后面慢慢弄好了,写出来记录下。
步骤上大致都是网上说的步骤:
1.在webview 加载url的时候设置cookie的HeaderFields 。
这样进入页面会带入cookie,具体做法如下:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:self.pathString]];
NSDictionary*headFields = request.allHTTPHeaderFields;
NSString*cookie = headFields[@"Cookie"];
if(cookie ==nil) {
[requestaddValue:[self cookieFromStage] forHTTPHeaderField:@"Cookie"];
}
[self.webView loadRequest:request];
- (NSString*)cookieFromStage
{
NSArray *cookiesArray = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
NSDictionary *cookieDict = [NSHTTPCookie requestHeaderFieldsWithCookies:cookiesArray];
NSString *cookie = [cookieDict objectForKey:@"Cookie"];
return cookie;
}
第二步,是在h5页面如果有ajax请求数据的时候给前端人员带过去cookie。这里需要用js,设置document.cookie。我的代码大致如下:
WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
config.preferences = [[WKPreferences alloc] init];
config.preferences.minimumFontSize = 10.0;
config.preferences.javaScriptEnabled = YES;
config.preferences.javaScriptCanOpenWindowsAutomatically = NO;
config.processPool = [[WKProcessPool alloc] init];
// //添加Cookie
NSMutableString *cookieValue = [[NSMutableString alloc] init];
NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for(NSHTTPCookie*cookiein[cookieJarcookies]) {
NSString*appendString = [NSStringstringWithFormat:@"%@=%@", cookie.name, cookie.value];
[cookieValueappendFormat:@"document.cookie='%@;expires=1;path=/'", appendString];//
}
WKUserContentController* userContentController =WKUserContentController.new;
WKUserScript* cookieScript = [[WKUserScriptalloc]
initWithSource: cookieValue
injectionTime:WKUserScriptInjectionTimeAtDocumentStart
forMainFrameOnly:NO];
[userContentController addUserScript:cookieScript];
[userContentController addScriptMessageHandler:self.webMedianame:@"isNoTokenLogin"];
config.userContentController= userContentController;
self.webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height) configuration:config];
从NSHTTPCookieStorage缓存里面取出cookie,设置document.cookie,h5开发人员去取就行,这里有些网上代码直接没有拼接expires=1;path=/',我这边试了不行。后面还是带上expires=1;path=/'才行。查了资料说不设置失效时间也可以,但是我试了还是不行,最好还是加上吧。1表示失效时间1天。
在这里涉及到cookie的缓存问题。因为每次重新进入app,NSHTTPCookieStorage里面是空的。需要在进入首页请求数据的时候就设置上。
这里我是在网络请求框架里面加上了缓存cookie 与 设置cookie的操作。
if([pathhasSuffix:@"login"]) {
// 登录成功 缓存cookie
NSArray*cookies = [[NSHTTPCookieStoragesharedHTTPCookieStorage]cookies];
if(cookies && cookies.count) {
// 缓存cookie
NSData*cookieData = [NSKeyedArchiver archivedDataWithRootObject:cookies];
[[NSUserDefaults standardUserDefaults] setValue:cookieDataforKey:KTokenKey];
[[NSUserDefaults standardUserDefaults] synchronize];
}
}
每次网络请求的时候加上下面代码:
NSData *Cookiedata = [[NSUserDefaults standardUserDefaults] objectForKey:KTokenKey];
if(![self.apiPathhasSuffix:@"login"] && Cookiedata) {
// 如果请求头里面没有cookie 添加进cookiestage里
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
if(storage.cookies.count==0) {
NSArray*cookies = [NSKeyedUnarchiver unarchiveObjectWithData:Cookiedata];
for(NSHTTPCookie*cookieincookies) {
[storagesetCookie:cookie];
}
}
}
if([self.apiPathhasSuffix:@"login"])
{
// 登录的时候 清除 cookie
NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for(NSHTTPCookie *cookie in [storage cookies]) {
[storagedeleteCookie:cookie];
}
[[NSUserDefaults standardUserDefaults] removeObjectForKey:KTokenKey];
}
我是放在创建AFHTTPSessionManager的函数里的。
这样就差不多了,如果每次进入app,保证了NSHTTPCookieStorage始终有cookie。
ps:在自己的webviewcontroller里面
[userContentController addScriptMessageHandler:self.webMedia name:@"isNoTokenLogin"];
这句代码不能直接用 [userContentController addScriptMessageHandler:self name:@"isNoTokenLogin"];,self会跟userContentController循环引用上。设置一个中间类去执行代理方法就好。