iOS开发之cookie

文章目录

      • NSHTTPCookieStorage 管理cookie
      • NSURLSession管理cookie
        • 1.使用系统管理cookie的类NSHTTPCookieStorage管理cookie
        • 2.自己手动管理cookie
      • AFNetworking自己管理cookie
      • ASIHTTPRequest自己管理cookie
      • UIWebView和WKWebView的cookie管理机制

  • 最近公司项目安全检查检测到缓存中的用户名和密码,虽然已经加密,但还是不安全;所以公司要求用cookie或者token去请求数据。由于公司项目比较老,里面既用了ASIHTTPRequest框架,又用了AFNetworking框架,发现其实这两个框架默认都是自动保持cookie的,我们不用去刻意处理它(获取与上传)。但是由于想搞清楚还是研究了一下cookie,并用NSURLSessionASIHTTPRequestAFNetworking自己手动管理cookie
  • cookie: 是网站服务端为了辩别用户身份,在服务器端生生成并存储在用户本地终端(电脑、手机)上的数据。其实cookie主要是用来免密登录的,我们这只是通过用户名和密码获取一个身份令牌,用于后面的接口调用,更像是token

NSHTTPCookieStorage 管理cookie

  • NSHTTPCookieStorage提供了管理所有NSHTTPCookie对象的接口,在OS X里,cookie是在所有程序中共享的,而在iOS中,cookie只在当当前应用中有效。。Session Cookie(SessionOnly返回YES的Cookie)只能在单一进程中使用。

iOS开发之cookie_第1张图片

  • NSHTTPCookieStorage可以获取,删除,设置单例里面的cookies,设置cookie的管理策略等。
//只读的单例对象
@property(class, readonly, strong) NSHTTPCookieStorage *sharedHTTPCookieStorage;
//获取里面的cookie对象数组
@property (nullable , readonly, copy) NSArray *cookies;
//添加cookie
- (void)setCookie:(NSHTTPCookie *)cookie;
//删除cookie
- (void)deleteCookie:(NSHTTPCookie *)cookie;
//删除某个日期之前的cookie
- (void)removeCookiesSinceDate:(NSDate *)date API_AVAILABLE(macos(10.10), ios(8.0), watchos(2.0), tvos(9.0));
//设置cookie的管理策略
@property NSHTTPCookieAcceptPolicy cookieAcceptPolicy;
//获取对应url返回的cookie数组
- (nullable NSArray *)cookiesForURL:(NSURL *)URL;
  • NSHTTPCookie里面有个properties的属性,其组成如下:
<__NSArrayM 0x283bec540>(
<NSHTTPCookie
	version:0
	name:JSESSIONID
	value:A0787301B667F5E1C7B5BABAAE58B104
	expiresDate:'(null)'
	created:'2018-12-27 02:39:06 +0000'
	sessionOnly:TRUE
	domain:192.168.1.121
	partition:none
	sameSite:none
	path:/inner
	isSecure:FALSE
	isHTTPOnly: YES
 path:"/inner" isSecure:FALSE isHTTPOnly: YES>,
<NSHTTPCookie
	version:0
	name:token
	value:1545878346436_111_cd90cdd1-9938-4e18-8ccd-79ad54d5527c
	expiresDate:'2019-01-26 02:39:06 +0000'
	created:'2018-12-27 02:39:06 +0000'
	sessionOnly:FALSE
	domain:192.168.1.121
	partition:none
	sameSite:none
	path:/inner
	isSecure:FALSE
 path:"/inner" isSecure:FALSE>
)
name 必选 规定 cookie 的名称
value 必选 规定 cookie 的值
expire 可选 规定 cookie 的有效期
path 可选 规定 cookie 的服务器路径,只有该路劲下的文件接口才能使用
domain 可选 规定 cookie 的域名
secure 可选 规定是否通过安全的 HTTPS 连接来传输 cookie

其中sessionOnly:TRUE的cookie是后台服务器自动创建的。

  • cookiesession默认都是后台创建,后端会将cookie放在在responseheader中返回给前端,将session缓存在服务器中;前端获取到cookie可以自己手动保存,也可以交给NSHTTPCookieStorage单例来保存;前端将cookie放在requestheader中传给服务器,服务器会去查对应的session,然后去交换获得用户信息(用户登录ID等)请求接口,这就是整个cookie获取、设置和请求数据的流程。
  • 获取cookie的几种方法:
 //方式1 :  NSHTTPCookie获取cookie
               NSArray * array = [NSHTTPCookie cookiesWithResponseHeaderFields:httpresponse.allHeaderFields forURLresponse.URL];
                for (NSHTTPCookie * cookie in array) {
                    //保存到sharedHTTPCookieStorage中
                    [[NSHTTPCookieStorage sharedHTTPCookieStorage]setCookie:cookie];
                }
                
//方式2:NSHTTPURLResponse获取
NSHTTPURLResponse * httpresponse = (NSHTTPURLResponse *)response;
                NSDictionary * dic = httpresponse.allHeaderFields;
                //获取cookie字符串
                NSString * cookiesStr = [dic valueForKey:@"Set-Cookie"];
                
//方式3:NSHTTPCookieStorage获取cookie
NSArray * cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage]cookiesForURL:response.URL];
  • 多个cookie的格式通常为:cookie1=value1; cookie2=value2; cookie3=value3; 这里特别要注意,多个cookie之间用分号+空格分隔开,不是&也不是单纯的空格。我所了解到的iOS设置Cookie的方法有两种。
    设置cookie方式1:NSDictionary * dic = httpresponse.allHeaderFields;返回的字典有个"Set-Cookie"的字符串值就是多个cookie的默认样式,我们获取到后可以直接设置cookierequest的 header中。
{
    "Cache-Control" = "no-cache,must-revalidate";
    "Content-Length" = 7;
    Date = "Thu, 27 Dec 2018 07:11:51 GMT";
    Expires = "Thu, 01 Jan 1970 00:00:00 GMT";
    Pragma = "no-cache";
    Server = "Apache-Coyote/1.1";
    "Set-Cookie" = "JSESSIONID=D6F65DA599B3B6B22C1927C5D85B53F0; Path=/inner; HttpOnly, token=1545894711778_111_17906b71-9c77-48c5-8e5a-b9e52522a538; Expires=Sat, 26-Jan-2019 07:11:51 GMT; Path=/inner";
}
NSString * cookiesStr = [dic valueForKey:@"Set-Cookie"];
//设置cookies
 [request setValue:cookiesaStr forHTTPHeaderField:@"Cookie"];

设置cookie方式2:构建多个NSHTTPCookie实例对象的数组,根据NSHTTPCookie实例数组生成对应的HTTP cookie header,设置cookierequestheader中。

NSDictionary *properties1 = [NSDictionary dictionaryWithObjectsAndKeys:
                                @"domain.com", NSHTTPCookieDomain,
                                @"/", NSHTTPCookiePath,
                                @"userid", NSHTTPCookieName,
                                strUserId, NSHTTPCookieValue,
                                nil];
    
    NSDictionary *properties2 = [NSDictionary dictionaryWithObjectsAndKeys:
                                 @"domain.com", NSHTTPCookieDomain,
                                 @"/", NSHTTPCookiePath,
                                 @"pid", NSHTTPCookieName,
                                 pid, NSHTTPCookieValue,
                                 nil];
    
    
    NSHTTPCookie *cookie1 = [NSHTTPCookie cookieWithProperties:properties1];
    NSHTTPCookie *cookie2 = [NSHTTPCookie cookieWithProperties:properties2];
    NSArray* cookies = [NSArray arrayWithObjects: cookie1, cookie2, nil];
    //根据NSHTTPCookie实例数组生成对应的HTTP cookie header
    NSDictionary * headers = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
    //设置cookie到header中
    request.allHTTPHeaderFields = headers; 

NSURLSession管理cookie

  • NSURLSession中有两个+ (NSURLSession *)sessionWithConfiguration:(NSURLSessionConfiguration *)configuration;初始化方法,这个configuration可以给NSURLSession实例对象配置一下属性策略等,与cookie有关的属性有下:
//发送请求时是否设置cookie
@property BOOL HTTPShouldSetCookies;
//设置cookie的接收策略
@property NSHTTPCookieAcceptPolicy HTTPCookieAcceptPolicy;
typedef NS_ENUM(NSUInteger, NSHTTPCookieAcceptPolicy) {
    NSHTTPCookieAcceptPolicyAlways,//接收所有的cookie,默认策略.
    NSHTTPCookieAcceptPolicyNever,//不接收所有的cookie
    NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain//只接收main document domain中的cookie.
};
//保存设置cookie的,如果不设置默认是[NSHTTPCookieStorage sharedHTTPCookieStorage],设置为nil管理cookie
@property (nullable, retain) NSHTTPCookieStorage *HTTPCookieStorage;

所以NSURLSession多了一种设置cookie的方式,只要设置了HTTPCookieStorage属性就可以自动设置了cookie。

1.使用系统管理cookie的类NSHTTPCookieStorage管理cookie

我们请求完成后必须手动将cookie保存到[NSHTTPCookieStorage sharedHTTPCookieStorage]中,不会自动将响应体header中的cookie保存,下面是具体实例。

//获取cookie
- (void)getCookies1{
    NSURL * url = [NSURL URLWithString:@"http://192.168.1.121:8080/inner/mobile/actionSh/Abc!login.action?"];
    NSString * post = [NSString stringWithFormat:@"loginId=%@",@"111"];
    NSData * postData = [post dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"POST";
    request.HTTPBody = postData;
    //defaultSessionConfiguration 使用默认session配置,类似NSURLConnection的标准配置,使用硬盘来存储缓存数据,会将缓存、cookie等存在本地
    //ephemeralSessionConfiguration 临时session配置,与默认配置相比,不使用永久持存cookie、证书、缓存的配置,最佳优化数据传输。
    //backgroundSessionConfiguration 后台session配置,与默认配置类似,不同的是会在后台开启另一个线程来处理网络数据
    NSURLSessionConfiguration * defultConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
    //不允许设置cookie
    defultConfiguration.HTTPShouldSetCookies = NO;
    //设置不允许缓存cookiechelue
    defultConfiguration.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicyNever;
    //清除所有的cookie
    for(NSHTTPCookie *cookie in [NSHTTPCookieStorage sharedHTTPCookieStorage].cookies)
    {
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie: cookie];
   }
     NSLog(@"清除所有的cookies : %@",[NSHTTPCookieStorage sharedHTTPCookieStorage].cookies);
    defultConfiguration.HTTPCookieStorage = nil;
    NSURLSession * session = [NSURLSession sessionWithConfiguration:defultConfiguration delegate:nil delegateQueue:[NSOperationQueue currentQueue]];
    NSURLSessionTask * task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSLog(@"请求完成!!!");
        if (!error) {
            NSString * result = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
            if (result) {
                NSLog(@"解析成功:%@",result);
                NSLog(@"response:%@",response);
                NSHTTPURLResponse * httpresponse = (NSHTTPURLResponse *)response;
                NSDictionary * dic = httpresponse.allHeaderFields;
//                NSString * cookies = [dic valueForKey:@"Set-Cookie"];
//                NSLog(@"cookies : %@ --- %@",cookies,[NSThread currentThread]);
//                NSArray * NSArray = [[NSHTTPCookieStorage sharedHTTPCookieStorage]cookiesForURL:response.URL];
                //获取cookie
               NSArray * array = [NSHTTPCookie cookiesWithResponseHeaderFields:dic forURL:response.URL];
                for (NSHTTPCookie * cookie in array) {
                    //保存到sharedHTTPCookieStorage中
                    [[NSHTTPCookieStorage sharedHTTPCookieStorage]setCookie:cookie];
                }
               NSLog(@"NSHTTPCookieStorage :  %@",[NSHTTPCookieStorage sharedHTTPCookieStorage].cookies);
                
            }else{
                NSLog(@"解析失败!!!");
            }
        }else{
            NSLog(@"请求失败 : %@",error.localizedDescription);
        }
    }];
    [task resume];
}

//设置cookie
- (void)requestWithCookies1{
    NSString * urlStr = @"http://192.168.1.121:8080/inner/mobile/actionSh/Abc!getData.action?";
    //encode去掉中午和特殊字符
    urlStr = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    NSURL * url = [NSURL URLWithString:urlStr];
    NSURLRequest * request = [NSURLRequest requestWithURL:url];
    NSURLSessionConfiguration * defultConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
    defultConfiguration.HTTPShouldSetCookies = YES;
    defultConfiguration.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicyAlways;
    NSLog(@"NSHTTPCookieStorage :  %@",[NSHTTPCookieStorage sharedHTTPCookieStorage].cookies);
    defultConfiguration.HTTPCookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    NSURLSession * session = [NSURLSession sessionWithConfiguration:defultConfiguration delegate:nil delegateQueue:[NSOperationQueue currentQueue]];
    NSURLSessionTask * task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSLog(@"请求完成!!!");
        if (!error) {
            NSString * result = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
            if (result) {
                NSLog(@"解析成功:%@",result);
            }else{
                NSLog(@"解析失败!!!");
            }
        }else{
            NSLog(@"请求失败 : %@",error.localizedDescription);
        }
    }];
    [task resume];
}

2.自己手动管理cookie

上面的方法有时候并不能立即将cookie设置进去,所以我们自己手动管理cookie比较保险,就是在requestheader中设置cookie,在responseheader中获取到得cookie保存到偏好设置或单例中自己管理。

//获取cookie
- (void)getCookies2{
    NSURL * url = [NSURL URLWithString:@"http://192.168.1.121:8080/inner/mobile/actionSh/Abc!login.action?"];
    NSString * post = [NSString stringWithFormat:@"loginId=%@",@"111"];
    NSData * postData = [post dataUsingEncoding:NSUTF8StringEncoding];
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
    request.HTTPMethod = @"POST";
    request.HTTPBody = postData;
    NSURLSessionConfiguration * defultConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
    //不允许设置cookie
    defultConfiguration.HTTPShouldSetCookies = NO;
    //不接受cookie
    defultConfiguration.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicyNever;
    
    NSURLSession * session = [NSURLSession sessionWithConfiguration:defultConfiguration delegate:nil delegateQueue:[NSOperationQueue currentQueue]];
    NSURLSessionTask * task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSLog(@"请求完成!!!");
        if (!error) {
            NSString * result = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
            if (result) {
//                NSArray * cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage]cookiesForURL:response.URL];
                NSLog(@"解析成功:%@",result);
                NSLog(@"response:%@",response);
                NSHTTPURLResponse * httpresponse = (NSHTTPURLResponse *)response;
                NSDictionary * dic = httpresponse.allHeaderFields;
                //获取cookie字符串
                NSString * cookiesStr = [dic valueForKey:@"Set-Cookie"];
                NSData * cookiesData = [NSKeyedArchiver archivedDataWithRootObject:cookiesStr];
                //保存到偏好设置中
                [[NSUserDefaults standardUserDefaults] setValue:cookiesData forKey:@"BoncUserDefaultsCookie"];
                [[NSUserDefaults standardUserDefaults]synchronize];
            }else{
                NSLog(@"解析失败!!!");
            }
        }else{
            NSLog(@"请求失败 : %@",error.localizedDescription);
        }
    }];
    [task resume];
}


//设置cookie
- (void)requestWithCookies2{
    NSString * urlStr = @"http://192.168.1.121:8080/inner/mobile/actionSh/Abc!getData.action?";
    //encode去掉中午和特殊字符
    urlStr = [urlStr stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    NSURL * url = [NSURL URLWithString:urlStr];
    NSMutableURLRequest * request = [NSMutableURLRequest requestWithURL:url];
    NSData * cookiesData = [[NSUserDefaults standardUserDefaults] valueForKey:@"BoncUserDefaultsCookie"];
    NSString * cookiesaStr = [NSKeyedUnarchiver unarchiveObjectWithData:cookiesData];
    //设置cookies
    [request setValue:cookiesaStr forHTTPHeaderField:@"Cookie"];
    //如果是NSURLRequest,可用下面方式设置
//    request.allHTTPHeaderFields = nil;
    NSURLSessionConfiguration * defultConfiguration = [NSURLSessionConfiguration ephemeralSessionConfiguration];
    defultConfiguration.HTTPShouldSetCookies = NO;
    defultConfiguration.HTTPCookieAcceptPolicy = NSHTTPCookieAcceptPolicyNever;
    NSURLSession * session = [NSURLSession sessionWithConfiguration:defultConfiguration delegate:nil delegateQueue:[NSOperationQueue currentQueue]];
    NSURLSessionTask * task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSLog(@"请求完成!!!");
        if (!error) {
            NSString * result = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
            if (result) {
                NSLog(@"解析成功:%@",result);
            }else{
                NSLog(@"解析失败!!!");
            }
        }else{
            NSLog(@"请求失败 : %@",error.localizedDescription);
        }
    }];
    [task resume];
}

AFNetworking自己管理cookie

  • AFNetworking是自动保持cookie的,我们不用去刻意处理它(获取与上传),除非你有一些需要。这里要讲的是我们手动管理cookieAFNetworking中并没有专门为cookie封装的代码,不过底层使用的是NSURLRequest,所以我们可以获取到请求时服务器返回的cookie,然后保存起来(删除和保存由我们自己管理),请求时候设置到requestheader中即可。
  • 设置不保持cookie
//默认是YES,cookie会被存储在共享的 NSHTTPCookieStorage 容器中
_manager.requestSerializer.HTTPShouldHandleCookies = NO;
  • 获取cookie,并保存起来
      // 获取所有数据报头信息
        NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)task.response;
        NSDictionary *fields = [HTTPResponse allHeaderFields];
        // 获取cookie
        NSString *cookieString = [fields valueForKey:@"Set-Cookie"];
        //保存到偏好设置中
        [[NSUserDefaults standardUserDefaults] setObject:cookieString forKey:@"BoncUserDefaultsCookie"];
        [[NSUserDefaults standardUserDefaults]synchronize];
  • 设置cookie
   NSString * cookie = [[NSUserDefaults standardUserDefaults] valueForKey:@"BoncUserDefaultsCookie"];
    [self.manager.requestSerializer setValue:cookie forHTTPHeaderField:@"Cookie"];

ASIHTTPRequest自己管理cookie

  • ASIHTTPRequest是自动保持cookie的,如果我们所用cookie请求数据,默认情况下我们不需要做其他任何操作。不同于AFNetworking的是ASIHTTPRequestcookie进行了封装,不管是获取还是设置都及其方便,这里是我们自己管理cookie的做法。

  • 设置不保持cookie

//默认是YES,cookie会被存储在共享的 NSHTTPCookieStorage 容器中,并且会自动被其他request重用。
request.useCookiePersistence = NO;
//清空session期间创建的所有cookie
//[ASIFormDataRequest setSessionCookies:nil];
//清除session期间产生的所有的cookie和缓存的授权数据。
// [ASIFormDataRequest clearSession];
  • 获取和保存cookie:
 //获取cookie
 NSArray * cookies = [request responseCookies];
 //获取responseHeader
// NSDictionary *headers = [request responseHeaders];
 //保存cookie
 NSData * cookiesData = [NSKeyedArchiver archivedDataWithRootObject:cookies];
 [[NSUserDefaults standardUserDefaults]setValue:cookiesData forKey:@"BoncUserDefaultsCookies"];
 [[NSUserDefaults standardUserDefaults]synchronize];
  • 设置cookie
    //依然要设置不保持cookie,否则传递cookie就不是我们自己保存到cookie
    [request setUseCookiePersistence:NO];
    //取出cookie
    NSData * cookiesData = [[NSUserDefaults standardUserDefaults] valueForKey:@"BoncUserDefaultsCookies"];
    NSArray * cookies = [NSKeyedUnarchiver unarchiveObjectWithData:cookiesData];
     //设置cookie
    [request setRequestCookies:cookies.mutableCopy];
  • AFNetworkingASIHTTPRequest默认都是开启cookie的,并且都是用[NSHTTPCookieStorage sharedHTTPCookieStorage]管理cookie的,所有二者可以通用,我们这里手动管理cookie,可以自己控制cookie的生命周期,避免过期的情况。其实默认情况已经够我们正常使用了,这里需要注意点是默认都是开启cookie的情况下,如在我们登录获取cookie时候,一定要先清除cookie,否则可能出现退出登录(不退出应用)换了个用户登录,登录后的数据还是上个用户的信息(未清除jsessionID),虽然可以交给后台取处理(后台判断是不是登录接口,如果是就不取cookie),但我们客户端也应该处理一下,避免该错误的发生。

AFNetworking请求登录接口时候清除cookie:

AFHTTPSessionManager  * manager =  [AFHTTPSessionManager manager];
[manager.requestSerializer setValue:nil forHTTPHeaderField:@"Cookie"];
//有时候这样设置并不好使,虽然也是在不保持cookie,但[NSHTTPCookieStorage sharedHTTPCookieStorage]还是保持了cookie,这样jsessionID并没有清除,所以为保险起见要清空[NSHTTPCookieStorage sharedHTTPCookieStorage]里面的cookies
- (void)clearCookies{
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    NSArray *_tmpArray = [NSArray arrayWithArray:[cookieStorage cookies]];
    for (id obj in _tmpArray) {
        [cookieStorage deleteCookie:obj];
    }
}

ASIHTTPRequest请求登录接口时候清除cookie:

[ASIFormDataRequest setSessionCookies:nil];

UIWebView和WKWebView的cookie管理机制

  • UIWebView会将NSHttpRequest的所有请求产生的cookie自动保存到NSHTTPCookieStorage容器中,并且在同一个app内多个UIWebView之间共享,不需要我们做任何操作,在后续访问中会将 cookie 自动带到request 请求当中。

  • WKWebViewcookie问题在于 WKWebView发起的请求不会自动带上存储于 NSHTTPCookieStorage容器中的Cookie,实践发现WKWebView实例其实也会将cookie存储于 NSHTTPCookieStorage 中,但存储时机有延迟,在iOS 8上,当页面跳转的时候,当前页面的 cookie 会写入NSHTTPCookieStorage中,而在 iOS 10 上,JS 执行 document.cookie 或服务器 set-cookie注入的 cookie会很快同步到 NSHTTPCookieStorage中,在执行 [WKWebView loadReques:] 前将 NSHTTPCookieStorage中的内容复制到 WKHTTPCookieStore中,以此来达到 WKWebView cookie注入的目的。


  • Demo下载地址: OS开发之cookie研究demo

  • 参考文章:
    iOS平台下cookie的使用
    ios AFNetworking—cookie(session)保持登陆会话状态
    ASIHTTPRequest-Cookie的使用
    UIWebView和WKWebView的cookie管理机制

你可能感兴趣的:(iOS,OC)