之前做項目的時候服務器那邊使用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循環引用上。設置一個中間類去執行代理方法就好。