Cookie 的緩存使用。WKWebView 與h5的交互

之前做項目的時候服務(wù)器那邊使用cookie來判斷用戶登錄狀態(tài)的,讓后用H5頁面的時候需要傳入cookie,但是wkwebview又不支持直接使用NSHTTPCookieStorage里面的Cookie,按照網(wǎng)上寫的接入都有點問題,后面慢慢弄好了,寫出來記錄下。

步驟上大致都是網(wǎng)上說的步驟:

1.在webview 加載url的時候設(shè)置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請求數(shù)據(jù)的時候給前端人員帶過去cookie。這里需要用js,設(shè)置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,設(shè)置document.cookie,h5開發(fā)人員去取就行,這里有些網(wǎng)上代碼直接沒有拼接expires=1;path=/',我這邊試了不行。后面還是帶上expires=1;path=/'才行。查了資料說不設(shè)置失效時間也可以,但是我試了還是不行,最好還是加上吧。1表示失效時間1天。

在這里涉及到cookie的緩存問題。因為每次重新進入app,NSHTTPCookieStorage里面是空的。需要在進入首頁請求數(shù)據(jù)的時候就設(shè)置上。

這里我是在網(wǎng)絡(luò)請求框架里面加上了緩存cookie 與 設(shè)置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];

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

每次網(wǎng)絡(luò)請求的時候加上下面代碼:

? ? 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];

? ? }

我是放在創(chuàng)建AFHTTPSessionManager的函數(shù)里的。

這樣就差不多了,如果每次進入app,保證了NSHTTPCookieStorage始終有cookie。


ps:在自己的webviewcontroller里面

? ? [userContentController addScriptMessageHandler:self.webMedia name:@"isNoTokenLogin"];

這句代碼不能直接用? ? [userContentController addScriptMessageHandler:self ?name:@"isNoTokenLogin"];,self會跟userContentController循環(huán)引用上。設(shè)置一個中間類去執(zhí)行代理方法就好。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容