htttp网络请求cookie的读取与写入(NSHTTPCookieStorage)

 

一.Cookie

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。

二.NSHTTPCookie

在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变化时发出此通知。

你可能感兴趣的:(iOS)