Cookie是在客户端存储服务器状态的一种机制,Web服务器可以通过Set-Cookie或者Set-Cookie2 HTTP头部设置Cookie。
Cookie可以分为两类,会话Cookie和持久Cookie,会话Cookie是临时Cookie,当前会话结束(浏览器退出)时Cookie会被删除。持久Cookie会存储在用户的硬盘上,浏览器退出,然后重新启动后Cookie仍然存在。会话Cookie和持久Cookie的区别在于过期时间,如果设置了Discard参数(Cookie 版本1)或者没有设置Expires(Cookie版本0)或Max-Age(Cookie版本1)设置过期时间,则此Cookie为会话Cookie
Cookie有两个版本,一个是版本0(Netscape Cookies)和版本1(RFC 2965),目前大多数服务器使用的Cookie 0。
在iOS中使用NSHTTPCookie类封装一条cookie,通过NSHTTPCookie的方法读取到cookie的通用属性。
可以通过手工赋值的方式创建Cookie,如
+ (id)cookieWithProperties:(NSDictionary *)properties;
- (id)initWithProperties:(NSDictionary *)properties;
也可以从Cookie中读取到所有属性。
- (NSDictionary *)properties;
使用NSHTTPCookie的类方法可以将NSHTTPCookie实例与HTTP cookie header相互转换.
根据NSHTTPCookie实例数组生成对应的HTTP cookie header
+ (NSDictionary *)requestHeaderFieldsWithCookies:(NSArray *)cookies;
从headerFileds中读取到Cookie相关内容,生成NSHTTPCookie实例对象数组。
+ (NSArray *)cookiesWithResponseHeaderFields:(NSDictionary *)headerFields forURL:(NSURL *)theURL;
该方法会忽略headerFileds中与cookie无关的字段,如果headerFileds中的cookie没有指定domain,则使用theURL的domain,如果没有指定path,则使用”/”.
除非NSURLRequest明确指定不使用cookie(HTTPShouldHandleCookies设为NO),否则URL loading system会自动为NSURLRequest发送合适的存储cookie。从NSURLResponse返回的cookie也会根据当前的cookie访问策略(cookie acceptance policy)接收到系统中。
应用如下
1.原生NSURLConnection写法
一.获取cookie
- (IBAction)cookieTouched:(id)sender {
NSURL *url = [NSURL URLWithString:@"http://xxx.xxx"];
NSURLRequest *request = [NSURLRequest requestWithURL:url]
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:3];
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
[NSURLConnection sendAsynchronousRequest:request
queue:queue
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error){
//转换NSURLResponse成为HTTPResponse
NSHTTPURLResponse *HTTPResponse = (NSHTTPURLResponse *)response;
//获取headerfields
NSDictionary *fields = [HTTPResponse allHeaderFields];//原生NSURLConnection写法
// NSDictionary *fields = [operation.response allHeaderFields]; //afnetworking写法
NSLog(@"fields = %@",[fields description]);
//获取cookie方法1
// NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:fields forURL:url];
//获取cookie方法2
//NSString *cookieString = [[HTTPResponse allHeaderFields] valueForKey:@"Set-Cookie"];
//获取cookie方法3
NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in [cookieJar cookies]) {
NSLog(@"cookie%@", cookie);
}
}];
}
2.AFNetworking 写法
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFCompoundResponseSerializer serializer];
//demo中的api返回的是html数据,不是json
[manager POST:@"http://xxx.xxx" parameters:nil progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"\n======================================\n");
NSDictionary *fields = ((NSHTTPURLResponse*)task.response).allHeaderFields;
NSLog(@"fields = %@",[fields description]);
NSURL *url = [NSURL URLWithString:@"http://xxx.xxx"];
NSLog(@"\n======================================\n");
//获取cookie方法1
NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:fields forURL:url];
for (NSHTTPCookie *cookie in cookies) {
NSLog(@"cookie,name:= %@,valuie = %@",cookie.name,cookie.value);
}
NSLog(@"\n======================================\n");
// //获取cookie方法2
// NSString *cookies2 = [((NSHTTPURLResponse*)task.response) valueForKey:@"Set-Cookie"];
// NSLog(@"cookies2 = %@",[cookies2 description]);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];
3.清空Cookie
NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray *cookieArray = [NSArray arrayWithArray:[cookieJar cookies]];
for (NSHTTPCookie *obj in cookieArray) {
[cookieJar deleteCookie:obj];
}
4.手动设置Cookie 手动设置的Cookie不会自动持久化到沙盒
//第一次请求手动设置个cookie
-(void)test1:(NSString*)urlString{
NSURL *url = [NSURL URLWithString:@"http://xxx.xxx"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
[cookieProperties setObject:@"username" forKey:NSHTTPCookieName];
[cookieProperties setObject:@"my ios cookie" forKey:NSHTTPCookieValue];
[cookieProperties setObject:@"dev.skyfox.org" forKey:NSHTTPCookieDomain];
[cookieProperties setObject:@"dev.skyfox.org" forKey:NSHTTPCookieOriginURL];
[cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
[cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];
[cookieProperties setObject:[NSDate dateWithTimeIntervalSinceNow:60*60] forKey:NSHTTPCookieExpires];//设置失效时间
[cookieProperties setObject:@"0" forKey:NSHTTPCookieDiscard]; //设置sessionOnly
NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
[self.myWebView loadRequest:request];
}
//第二次请求会自动带上Cookie
- (IBAction)test2:(id)sender {
NSURL *url = [NSURL URLWithString:@"http://xxx.xxx"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[self.mywebview2 loadRequest:request];
}
//设置多个Cookie
NSArray * heardCookie = [NSHTTPCookie cookiesWithResponseHeaderFields:[NSDictionary
dictionaryWithObject:[[NSString alloc]
initWithFormat:@"cookieName=%@", userstring] //这里的cookieName要后台给
forKey:@"Set-Cookie"]
forURL:[NSURL URLWithString:@"http://"]];
[[NSHTTPCookieStorage sharedHTTPCookieStorage]setCookies:heardCookie forURL:[NSURL URLWithString:@"http://"] mainDocumentURL:nil];
//passwd
NSArray * heardCookie = [NSHTTPCookie cookiesWithResponseHeaderFields:[NSDictionary
dictionaryWithObject:[[NSString alloc]
initWithFormat:@"cookiePasswd =%@", passString] //cookiePasswd也是后台给
forKey:@"Set-Cookie"]
forURL:[NSURL URLWithString:@"http://"]];
[[NSHTTPCookieStorage sharedHTTPCookieStorage]setCookies:heardCookie forURL:[NSURL URLWithString:@"http://"] mainDocumentURL:nil];
//另一种设置Cookie的方法
NSString* cookie = [[NSString alloc] initWithFormat:@"accessToken=%@;path=/;domain=%@;httponly", token, host];
NSArray *headeringCookie = [NSHTTPCookie
cookiesWithResponseHeaderFields:
@{
@"Set-Cookie":cookie,
}
forURL:[NSURL URLWithString:url]];
// 通过setCookies方法,完成设置,这样只要一访问URL为HOST的网页时,会自动附带上设置好的header
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:headeringCookie forURL:[NSURL URLWithString:url]
mainDocumentURL:nil];
通过NSHTTPCookieStorage可读取/修改cookie接收策略,默认为NSHTTPCookieAcceptPolicyAlways.
- (NSHTTPCookieAcceptPolicy)cookieAcceptPolicy;
- (void)setCookieAcceptPolicy:(NSHTTPCookieAcceptPolicy)aPolicy.
一共有三种cookie accept policy,
typedef enum {
NSHTTPCookieAcceptPolicyAlways,
NSHTTPCookieAcceptPolicyNever,
NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
} NSHTTPCookieAcceptPolicy;
NSHTTPCookieAcceptPolicyAlways:接收所有cookie,默认策略.
NSHTTPCookieAcceptPolicyNever: 拒绝所有cookie
NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain:只接收main document domain中的cookie.
NSHTTPCookieManagerCookiesChangedNotification
当NSHTTPCookieStorage实例中的cookies变化时发出此通知。
NSHTTPCookieManagerAcceptPolicyChangedNotification
当NSHTTPCookieStorage实例的cookie acceptance policy变化时发出此通知。