Cookie簡介 說到Cookie,或許有些小夥伴會比較陌生,有些小夥伴會比較熟悉。若是項目中,全部頁面都是純原生來實現的話,通常Cookie這個東西或許咱們永遠也不會接觸到。可是,這裏仍是要說一下Cookie,由於它真的很重要,由它產生的一些坑也不少。html
Cookie 在 web中應用比較多,主要是記錄一個狀態,好比我在網頁上登陸了,我就能夠拿到網頁登陸後 Cookie,下次再 Cookie 的生效期內我就能夠不用輸入帳號密碼,直接跳轉登陸狀態,在App中,Cookie最經常使用的也就是維持登陸狀態了.由於筆者最近就在作這個,其中也遇到過不少坑,這裏說先踩坑和用法ios
iOS Cookie 的管理web
NSHTTPCookie和NSHTTPCookieStorage iOS中進行HTTP網絡請求Cookie管理主要由兩個類負責,一個類是NSHTTPCookieStorage類,一個是NSHTTPCookie類。設計模式
NSHTTPCookieStorage跨域
NSHTTPCookieStorage類採用單例的設計模式,其中管理着全部HTTP請求的Cookie信息 官方解釋:NSHTTPCookieStorage 是一個用來管理 cookie 存儲的單例。一個 NSHTTPCookie 單例表明一個 cookie。一般來說,cookie 能夠在應用間共享,而且在進程之間保持同步。 對於單進程,Session cookies (這裏的 cookie 對象的 isSessionOnly 方法返回 YES
)是局部的而且不能被共享。數組
經常使用方法緩存
// 獲取單例對象 + (NSHTTPCookieStorage *)sharedHTTPCookieStorage; // 全部Cookie數據數組 其中存放NSHTTPCookie對象 @property (nullable , readonly, copy) NSArray<NSHTTPCookie *> *cookies; // 手動設置一條Cookie數據 - (void)setCookie:(NSHTTPCookie *)cookie; // 刪除某條Cookie信息 - (void)deleteCookie:(NSHTTPCookie *)cookie; // 刪除某個時間後的全部Cookie信息 iOS8後可用 - (void)removeCookiesSinceDate:(NSDate *)date NS_AVAILABLE(10_10, 8_0); // 獲取某個特定URL的全部Cookie數據 - (nullable NSArray<NSHTTPCookie *> *)cookiesForURL:(NSURL *)URL; // 爲某個特定的URL設置Cookie - (void)setCookies:(NSArray<NSHTTPCookie *> *)cookies forURL:(nullable NSURL *)URL mainDocumentURL:(nullable NSURL *)mainDocumentURL; // Cookie數據的接收協議 枚舉以下: typedef NS_ENUM(NSUInteger, NSHTTPCookieAcceptPolicy) { NSHTTPCookieAcceptPolicyAlways, //接收全部Cookie信息 NSHTTPCookieAcceptPolicyNever, //不接收全部Cookie信息 NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain //只接收主文檔域的Cookie信息 }; @property NSHTTPCookieAcceptPolicy cookieAcceptPolicy; 系統下面的兩個通知與Cookie管理有關: 聽說,在Mac OS是cookie能夠共享的(Session cookies 不能共享),在Mac OS app中更改cookie的接收策略會影響到其餘正在運行的在使用cookie storage的app.這時NSHTTPCookieStorage會發出兩個通知: // Cookie數據的接收協議改變時發送的通知 FOUNDATION_EXPORT NSString * const NSHTTPCookieManagerAcceptPolicyChangedNotification; // 管理的Cookie數據發生變化時發送的通知 FOUNDATION_EXPORT NSString * const NSHTTPCookieManagerCookiesChangedNotification;
NSHTTPCookie介紹安全
NSHTTPCookie是具體的HTTP請求Cookie數據對象.cookie
// 下面兩個方法用於對象的建立和初始化 都是經過字典進行鍵值設置 - (nullable instancetype)initWithProperties:(NSDictionary<NSString *, id> *)properties; + (nullable NSHTTPCookie *)cookieWithProperties:(NSDictionary<NSString *, id> *)properties; // 返回Cookie數據中可用於添加HTTP頭字段的字典 + (NSDictionary<NSString *, NSString *> *)requestHeaderFieldsWithCookies:(NSArray<NSHTTPCookie *> *)cookies; // 從指定的響應頭和URL地址中解析出Cookie數據 + (NSArray<NSHTTPCookie *> *)cookiesWithResponseHeaderFields:(NSDictionary<NSString *, NSString *> *)headerFields forURL:(NSURL *)URL; // Cookie數據中的屬性字典 @property (nullable, readonly, copy) NSDictionary<NSString *, id> *properties; // 請求響應的版本 @property (readonly) NSUInteger version; // 請求相應的名稱 @property (readonly, copy) NSString *name; // 請求相應的值 @property (readonly, copy) NSString *value; // 過時時間 @property (nullable, readonly, copy) NSDate *expiresDate; // 請求的域名 @property (readonly, copy) NSString *domain; //請求的路徑 @property (readonly, copy) NSString *path; // 是不是安全傳輸 @property (readonly, getter=isSecure) BOOL secure; // 是否只發送HTTP的服務 @property (readonly, getter=isHTTPOnly) BOOL HTTPOnly; // 響應的文檔 @property (nullable, readonly, copy) NSString *comment; // 相應的文檔URL @property (nullable, readonly, copy) NSURL *commentURL; // 服務端口列表 @property (nullable, readonly, copy) NSArray<NSNumber *> *portList;
HTTP cookie的屬性鍵 屬性 | 解讀網絡
NSHTTPCookieName | Cookie的名字 NSHTTPCookieValue | Cookie的值 NSHTTPCookieOriginURL | 和域名同樣,NSHTTPCookieDomain或NSHTTPCookieOriginURL必須指定一個值 NSHTTPCookieVersion | 接收器的版本 NSHTTPCookieDomain | 域名 NSHTTPCookiePath | Cookie 存放路徑 NSHTTPCookieSecure | Cookie是否只應經過安全通道發送,設置Cookie的secure屬性爲true。 只會在HTTPS和SSL等安全協議中傳輸此類Cookie。默認爲false NSHTTPCookieComment | 包含Cookie的評論,只有有效的版本1的cookies或更高版本。 這頭字段是可選的 NSHTTPCookieCommentURL | 接收器的評論URL NSHTTPCookieDiscard | Cookie是否應在會議結束時丟棄NSString,字符串值必須是「true」或「假」。 這個字段是可選的。 默認爲「假」,除非這是Cookie是第1版或以上, NSHTTPCookieMaximumAge未指定,在這種狀況下,它被假定爲「TRUE」 NSHTTPCookieMaximumAge | NSString對象,包含一個整數,在Cookie內保持最多幾秒 。 僅適用於第1版和更高版本的有效。 默認爲「0」。 此字段是可選的 NSHTTPCookiePort | 接收機的端口
- UIWebView的 Cookie 機制
UIWebView 在瀏覽網頁後會將網頁中的 cookie 自動存入 NSHTTPCookieStorage 標準容器中,[NSHTTPCookieStorage sharedHTTPCookieStorage]這個單例管理,在後續訪問中會將 cookie 自動帶到 request 請求當中。而且在同一個app內多個UIWebView之間共享。
- webView 中獲取 cookie
//加載成功 - (void)webViewDidFinishLoad:(UIWebView *)webView { NSString *requestUrl = webView.request.URL.absoluteString; NSLog(@" requestUrl: %@",requestUrl); //設置原始 cookie 根據key 存儲本地 NSMutableArray *cookieArray = [[NSMutableArray alloc] init]; //網頁加載完成取出 cookies NSArray *nCookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]; NSHTTPCookie *cookie; for (id c in nCookies) { if ([c isKindOfClass:[NSHTTPCookie class]]) { cookie=(NSHTTPCookie *)c; //我這裏是cookie存入字典中 去重 if ([cookie value]) { //若是 vaule 值不爲 nil 存入字典中, [self.mutableDic setValue:[cookie value] forKey:[cookie name]]; } //設置原始 cookie NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary]; [cookieProperties setObject:cookie.name forKey:NSHTTPCookieName]; [cookieProperties setObject:cookie.value forKey:NSHTTPCookieValue]; [cookieProperties setObject:cookie.domain forKey:NSHTTPCookieDomain]; [cookieProperties setObject:cookie.path forKey:NSHTTPCookiePath]; [cookieProperties setObject:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires]; [cookieArray addObject:cookieProperties]; [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie]; } } //cookie 存入本地 [[NSUserDefaults standardUserDefaults] setObject:cookieArray forKey:@"cookieArray"]; [[NSUserDefaults standardUserDefaults] synchronize]; //下面 cookie 去重是爲了獲得 key=Value;形式的字符串,這裏因爲我有需求這樣作,實際中下面能夠忽略 NSMutableString *cookieValue = [NSMutableString stringWithFormat:@""]; // cookie重複,先放到字典進行去重,再進行拼接 for (NSString *key in self.mutableDic) { NSString *appendString = [NSString stringWithFormat:@"%@=%@;", key, [self.mutableDic valueForKey:key]]; [cookieValue appendString:appendString]; } NSLog(@"######################## %@ ####################",cookieValue);
- 設置 cookie
NSMutableArray* cookieDictionary = [[NSUserDefaults standardUserDefaults] valueForKey:@"cookieArray"]; NSLog(@"cookie dictionary found is %@",cookieDictionary); if (cookieDictionary) { for (NSInteger i = 0; i < cookieDictionary.count; i++) { NSLog(@"cookie found is %@",[cookieDictionary objectAtIndex:i]); NSDictionary *cookieDic = [cookieDictionary objectAtIndex:i]; NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieDic]; [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie]; } } //設置請求以前加載 cookie 確保 cookie 在請求頭以前設置 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.URLString] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; //加載網頁 [self.webView loadRequest:request];
- 刪除 cookie
// 清空 cookie - (void)deleteCookie { // 清空 cookie NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage]; NSArray *_tmpArray = [NSArray arrayWithArray:[cookieJar cookies]]; for (id obj in _tmpArray) { [cookieJar deleteCookie:obj]; } }
- WKWebView 的 Cookie 機制
NSURLCache和NSHTTPCookieStroage沒法操做(WKWebView)WebCore進程的緩存和Cookie WKWebView實例將會忽略任何的默認網絡存儲器(NSURLCache, NSHTTPCookieStorage, NSCredentialStorage) 和一些標準的自定義網絡請求類(NSURLProtocol,等等.),WKWebView實例不會把Cookie存入到App標準的的Cookie容器(NSHTTPCookieStorage)中,由於 NSURLSession/NSURLConnection等網絡請求使用NSHTTPCookieStorage進行訪問Cookie,因此不能訪問WKWebView的Cookie,現象就是WKWebView存了Cookie,其餘的網絡類如NSURLSession/NSURLConnection卻看不到。這是不少人的說法。 還有一種是說法是經過實踐發現 WKWebView 實例其實也會將 Cookie 存儲於 NSHTTPCookieStorage 中,但存儲時機有延遲,由於WKWebView內也有cookie的容器,並且每隔一段時間就和app側NSHTTPCookieStorage進行同步,並且這個同步是進程級別的同步,並且這個同步是單向。 至於以上兩種說法,最終WKWebView Cookie 問題在於 WKWebView 發起的請求不會自動帶上存儲於 NSHTTPCookieStorage 容器中的 Cookie。
-
iOS11 iOS11 的 API 能夠解決該問題,只要是存在 WKHTTPCookieStore 裏的 cookie,WKWebView 每次請求都會攜帶,存在 NSHTTPCookieStorage 的cookie,並不會每次都攜帶。因而會發生首次 WKWebView 請求不攜帶 Cookie 的問題。
-
ios 11 WKWebView cookie 的注入
在執行 -[WKWebView loadReques:] 前將 NSHTTPCookieStorage 中的內容複製到 WKHTTPCookieStore 中,以此來達到 WKWebView Cookie 注入的目的。示例代碼以下:
[self copyNSHTTPCookieStorageToWKHTTPCookieStoreWithCompletionHandler:^{ NSURL *url = [NSURL URLWithString:@"https://www.v2ex.com"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [_webView loadRequest:request]; }];
- (void)copyNSHTTPCookieStorageToWKHTTPCookieStoreWithCompletionHandler:(nullable void (^)())theCompletionHandler; { NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]; WKHTTPCookieStore *cookieStroe = self.webView.configuration.websiteDataStore.httpCookieStore; if (cookies.count == 0) { !theCompletionHandler ?: theCompletionHandler(); return; } for (NSHTTPCookie *cookie in cookies) { [cookieStroe setCookie:cookie completionHandler:^{ if ([[cookies lastObject] isEqual:cookie]) { !theCompletionHandler ?: theCompletionHandler(); return; } }]; } }
-
ios11 以前 注入 Cookie 就是從以前保存 cookie 的 NSHTTPCookieStorage 中取出相關 Cookie,而後在再次請求訪問的時候在 request 中注入 Cookie。注入Cookie一樣有多種方式。
-
1.JS注入1
//取出 storage 中的cookie並將其拼接成正確的形式 NSArray<NSHTTPCookie *> *tmp = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]; NSMutableString *jscode_Cookie = [@"" mutableCopy]; [tmp enumerateObjectsUsingBlock:^(NSHTTPCookie * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { NSLog(@"%@ = %@", obj.name, obj.value); [jscode_Cookie appendString:[NSString stringWithFormat:@"document.cookie = '%@=%@';", obj.name, obj.value]]; }]; WKUserContentController* userContentController = WKUserContentController.new; WKUserScript * cookieScript = [[WKUserScript alloc] initWithSource: @"" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO]; [userContentController addUserScript:cookieScript]; WKWebViewConfiguration* webViewConfig = WKWebViewConfiguration.new; webViewConfig.userContentController = userContentController; WKWebView * webView = [[WKWebView alloc] initWithFrame:CGRectMake(/*set your values*/) configuration:webViewConfig];
- JS注入2
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation { [webView evaluateJavaScript:@"document.cookie ='TeskCookieKey1=TeskCookieValue1';" completionHandler:^(id result, NSError *error) { //... }]; }
- NSMutableURLRequest 注入Cookie
NSURL *url = request.URL; NSMutableString *cookies = [NSMutableString string]; NSMutableURLRequest *requestObj = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; NSArray *tmp = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]; NSDictionary *dicCookies = [NSHTTPCookie requestHeaderFieldsWithCookies:tmp]; NSString *cookie = [self readCurrentCookie]; [requestObj setValue:cookie forHTTPHeaderField:@"Cookie"]; [_webView loadRequest:requestObj]; -(NSString *)readCurrentCookie { NSMutableDictionary *cookieDic = [NSMutableDictionary dictionary]; NSMutableString *cookieValue = [NSMutableString stringWithFormat:@""]; NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage]; for (NSHTTPCookie *cookie in [cookieJar cookies]) { [cookieDic setObject:cookie.value forKey:cookie.name]; } // cookie重複,先放到字典進行去重,再進行拼接 for (NSString *key in cookieDic) { NSString *appendString = [NSString stringWithFormat:@"%@=%@;", key, [cookieDic valueForKey:key]]; [cookieValue appendString:appendString]; } return cookieValue; }
獲取Cookie
因爲 WKWebView 的 Cookie 存儲容器 WKWebsiteDataStore 是私有存儲,因此沒法從這裏獲取到Cookie,目前的方法是(1)從網站返回的 response headerfields 中獲取。(2)經過調用js的方法獲取 cookie。
- 1.從網站返回的 response headerfields 中獲取,由於cookie都存在http respone的headerfields,找到能得到respone的WKWebView回調,打印
- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler { NSHTTPURLResponse *response = (NSHTTPURLResponse *)navigationResponse.response; NSArray *cookies =[NSHTTPCookie cookiesWithResponseHeaderFields:[response allHeaderFields] forURL:response.URL]; //讀取wkwebview中的cookie 方法1 for (NSHTTPCookie *cookie in cookies) { // [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie]; NSLog(@"wkwebview中的cookie:%@", cookie); } //讀取wkwebview中的cookie 方法2 讀取Set-Cookie字段 NSString *cookieString = [[response allHeaderFields] valueForKey:@"Set-Cookie"]; NSLog(@"wkwebview中的cookie:%@", cookieString); //看看存入到了NSHTTPCookieStorage了沒有 NSHTTPCookieStorage *cookieJar2 = [NSHTTPCookieStorage sharedHTTPCookieStorage]; for (NSHTTPCookie *cookie in cookieJar2.cookies) { NSLog(@"NSHTTPCookieStorage中的cookie%@", cookie); } //下面是將 原始cookie本地 化 NSMutableArray *cookieArray = [[NSMutableArray alloc] init]; for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) { NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary]; [cookieProperties setObject:cookie.name forKey:NSHTTPCookieName]; [cookieProperties setObject:cookie.value forKey:NSHTTPCookieValue]; [cookieProperties setObject:cookie.domain forKey:NSHTTPCookieDomain]; [cookieProperties setObject:cookie.path forKey:NSHTTPCookiePath]; [cookieProperties setObject:[NSNumber numberWithInt:cookie.version] forKey:NSHTTPCookieVersion]; [cookieProperties setObject:[[NSDate date] dateByAddingTimeInterval:2629743] forKey:NSHTTPCookieExpires]; [cookieArray addObject:cookieProperties]; } [[NSUserDefaults standardUserDefaults] setValue:cookieArray forKey:@"cookieArray"]; [[NSUserDefaults standardUserDefaults] synchronize]; decisionHandler(WKNavigationResponsePolicyAllow); } // 頁面加載完成以後調用須要從新給WKWebView設置Cookie防止由於a標籤跳轉,致使下一次跳轉的時候Cookie丟失。 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{ //取出cookie NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; //js函數 NSString *JSFuncString = @"function setCookie(name,value,expires)\ {\ var oDate=new Date();\ oDate.setDate(oDate.getDate()+expires);\ document.cookie=name+'='+value+';expires='+oDate+';path=/'\ }\ function getCookie(name)\ {\ var arr = document.cookie.match(new RegExp('(^| )'+name+'=({FNXX==XXFN}*)(;|$)'));\ if(arr != null) return unescape(arr[2]); return null;\ }\ function delCookie(name)\ {\ var exp = new Date();\ exp.setTime(exp.getTime() - 1);\ var cval=getCookie(name);\ if(cval!=null) document.cookie= name + '='+cval+';expires='+exp.toGMTString();\ }"; //拼湊js字符串 NSMutableString *JSCookieString = JSFuncString.mutableCopy; for (NSHTTPCookie *cookie in cookieStorage.cookies) { NSString *excuteJSString = [NSString stringWithFormat:@"setCookie('%@', '%@', 1);", cookie.name, cookie.value]; [JSCookieString appendString:excuteJSString]; } //執行js [webView evaluateJavaScript:JSCookieString completionHandler:^(id obj, NSError * _Nullable error) { NSLog(@"%@",error); }]; }
- 經過 JS 獲取 cookie
- (void)webView:(WKWebView *)webView didFinishNavigation:(null_unspecified WKNavigation *)navigation { [webView evaluateJavaScript:[NSString stringWithFormat:@"document.cookie"] completionHandler:^(id _Nullable response, NSError * _Nullable error) { if (response != 0) { NSLog(@"\n\n\n\n\n\n document.cookie%@,%@",response,error); } }]; }
##注意 document.cookie 的方法獲取 cookie並不支持跨越獲取,若是設置 httponly則獲取不到 cookie 不管是(1)仍是(2)方法,彷佛都沒法解決302請求的 Cookie 問題。舉例來講,假設你要訪問網站A,在A中點擊登陸,跳轉頁面到B地址,在B中完成登陸以後302跳轉回A網站。此時cookie是存在於B地址的 response 中的,在A地址的 response 中並無 cookie 的字段。然而咱們只能獲取到A地址的 response ,沒法截獲到B地址的response。所以獲取不到該類型網站的 cookie 。 因爲我並無遇到302這樣的問題,全部看了下網上的資料,但願對遇到這個問題的小夥伴一下辦法,網上給出的解決辦法是:
- 1.加載一個本地爲空的html,域名指向你的第一次加載的url的域名。
//加載本地html [self.webView loadHTMLString:@"" baseURL:[NSURL URLWithString:@"https:/a.com"]];
- 2.經過如下方法,在第一次加載完成後,將須要設置的Cookies設置到WKWebView中,由於是加載的本地的html如下方法會當即執行。
// 頁面加載完成以後調用 - (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{ if (isFirstLoaded) { NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; //js函數 NSString *JSFuncString = @"function setCookie(name,value,expires)\ {\ var oDate=new Date();\ oDate.setDate(oDate.getDate()+expires);\ document.cookie=name+'='+value+';expires='+oDate+';path=/'\ }"; //拼湊js字符串,按照本身的需求拼湊Cookie NSMutableString *JSCookieString = JSFuncString.mutableCopy; for (NSHTTPCookie *cookie in cookieStorage.cookies) { if (![cookie.name isEqualToString:@"__cust"]) { NSString *excuteJSString = [NSString stringWithFormat:@"setCookie('%@', '%@', 3);", cookie.name, cookie.value]; [JSCookieString appendString:excuteJSString]; } } //執行js [webView evaluateJavaScript:JSCookieString completionHandler:^(id obj, NSError * _Nullable error) { //加載真正的第一次Request [self loadRealRequest]; }]; } }
若是cookie 存儲到本地獲取本地的 cookie
//修改從 storage 中讀取 cookie 的方法 -(NSString *)readCurrentCookie{ NSMutableArray* cookieDictionary = [[NSUserDefaults standardUserDefaults] valueForKey:@"cookieArray"]; NSLog(@"cookie dictionary found is %@",cookieDictionary); for (int i=0; i < cookieDictionary.count; i++) { NSLog(@"cookie found is %@",[cookieDictionary objectAtIndex:i]); NSMutableDictionary* cookieDictionary1 = [[NSUserDefaults standardUserDefaults] valueForKey:[cookieDictionary objectAtIndex:i]]; NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieDictionary1]; [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie]; } NSMutableDictionary *cookieDic = [NSMutableDictionary dictionary]; NSMutableString *cookieValue = [NSMutableString stringWithFormat:@""]; NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage]; for (NSHTTPCookie *cookie in [cookieJar cookies]) { [cookieDic setObject:cookie.value forKey:cookie.name]; } // cookie重複,先放到字典進行去重,再進行拼接 for (NSString *key in cookieDic) { NSString *appendString = [NSString stringWithFormat:@"%@=%@;", key, [cookieDic valueForKey:key]]; [cookieValue appendString:appendString]; } return cookieValue; }
清除 cookie
#pragma mark - 清空cookie -(void)deleCookie { // NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage]; // NSArray *_tmpArray = [NSArray arrayWithArray:[cookieJar cookies]]; // for (id obj in _tmpArray) { // [cookieJar deleteCookie:obj]; // } if (@available(iOS 9.0, *)) {//iOS9及以上 WKWebsiteDataStore *dateStore = [WKWebsiteDataStore defaultDataStore]; [dateStore fetchDataRecordsOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] completionHandler:^(NSArray<WKWebsiteDataRecord *> * __nonnull records) { for (WKWebsiteDataRecord *record in records) { //取消備註,能夠針對某域名作專門的清除,不然是所有清除 //if ( [record.displayName containsString:@"baidu"]) //{ [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:record.dataTypes forDataRecords:@[record] completionHandler:^ { NSLog(@"Cookies for %@ deleted successfully",record.displayName); }]; //} } }]; } else { //iOS9如下 NSString *libraryPath = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) objectAtIndex:0]; NSString *cookiesFolderPath = [libraryPath stringByAppendingString:@"/Cookies"]; NSError *errors; [[NSFileManager defaultManager] removeItemAtPath:cookiesFolderPath error:&errors]; } }
##最後 UIWebView 和 WKWebView 所遇到問題 cookie 同步,獲取,刪除,設置這些問題,目前就這麼多解決辦法吧,我一開始嘗試用 WKWebView 獲取 cookie 可是最後遇到網頁跨域問題以及低版本兼容問題我仍是換回 UIWebView 了,若是有更好的解決辦法能夠在下面留言,謝謝!
來自:http://www.javashuo.com/article/p-qwazqard-q.html
原文出處:https://www.cnblogs.com/benxiaokang/p/ios-uiwebview-he-wkwebview-de-cookie-huo-qu-she-zh.html