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

2016-03-15 11:31小小哆Objective-C相关,iOSDev评论(0)

当你访问一个网站时,NSURLRequest都会帮你主动记录下来你访问的站点设置的cookie,如果 Cookie 存在的话,会把这些信息放在 NSHTTPCookieStorage 容器中共享,当你下次再访问这个站点时,NSURLRequest会拿着上次保存下来了的cookie继续去请求。
同样适用于ASIHTTPRequest,AFNetworking,webView等,cookie常用于一些基于认证的网络请求

认识下NSHTTPCookieStorage
NSHTTPCookieStorage 实现了一个管理cookie的单例对象(只有一个实例),每个cookie都是NSHTTPCookie类的实例,最为一个规则,cookie在所有应用之间共享并在不同进程之间保持同步。Session cookie(一个isSessionOnly方法返回YES的cookie)只能在单一进程中使用。

Cookie
Cookie是由服务器端生成,发送给User-Agent(一般是浏览器或者客户端),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站地址时就发送该Cookie给服务器

HTTP header
HTTP header中包含HTTP请求与响应的操作参数. header属性定义了所传输数据的各种特性. header属性以属性名开始,以冒号结尾,最后是属性值.属性名及值会因应用的不同

一、iOS http网络请求cookie的读取与写入:

1.原生NSURLConnection写法

- (IBAction)cookieTouched:(id)sender {
    NSURL *url = [NSURL URLWithString:@"https://www.xsd.me/test.php"];
    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 写法

[[APIClient sharedClient] postPath:@"https://www.xsd.me/test.php" parameters:p success:^(AFHTTPRequestOperation *operation, id JSON) {
        NSDictionary *fields = [operation.response allHeaderFields]; //afnetworking写法
        NSLog(@"fields = %@",[fields description]);
        NSURL *url = [NSURL URLWithString:@"https://www.xsd.me/test.php"];
        //获取cookie方法1
         NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:fields forURL:url];
        //获取cookie方法2
        //NSString *cookieString = [[HTTPResponse allHeaderFields] valueForKey:@"Set-Cookie"];
 
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
      
    }];

二、清空cookie

NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
  NSArray *cookieArray = [NSArray arrayWithArray:[cookieJar cookies]];
  for (id obj in cookieArray) {
    [cookieJar deleteCookie:obj];
  }

三、手动设置Cookie 手动设置的Cookie不会自动持久化到沙盒

- (void)test1:(NSString*)urlString{
    NSURL *url = [NSURL URLWithString:@"https://www.xsd.me/test.php"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    
    NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
    [cookieProperties setObject:@"username" forKey:NSHTTPCookieName];
    [cookieProperties setObject:@"my ios cookie" forKey:NSHTTPCookieValue];
    [cookieProperties setObject:@"www.xsd.me" forKey:NSHTTPCookieDomain];
    [cookieProperties setObject:@"www.xsd.me" 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:@"https://www.xsd.me/test.php"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [self.mywebview2 loadRequest:request];
}

request还可以这样设置个cookie

[request setHTTPShouldHandleCookies:YES];
[request setValue:[NSString stringWithFormat:@"%@=%@", [cookie name], [cookie value]] forHTTPHeaderField:@"Cookie"];

四、Cookie的持久化存储

1.服务器端设置Cookie,以PHP为例

语法:

setcookie(name,value,expire,path,domain,secure)

参数 描述
name 必需。规定 cookie 的名称。
value 必需。规定 cookie 的值。
expire 可选。规定 cookie 的有效期。
path 可选。规定 cookie 的服务器路径。
domain 可选。规定 cookie 的域名。
secure 可选。规定是否通过安全的 HTTPS 连接来传输 cookie。

setcookie("TestCookie","my cookie value"); //没设置失效时间 关闭app后系统不会持久化Cookie
setcookie("TestCookie","my cookie value",time()+3600*24); //设置expire失效时间 关闭app后系统自动持久化Cookie

如果服务器设置了Cookie失效时间expiresDate ,sessionOnly:FALSE会被持久化到文件中,kill掉后系统自动保存,下次启动app会自动加载.binarycookies中的Cookies,以下是一条Cookie输出

<NSHTTPCookie version:0 name:"TestCookie" value:"my+cookie+value" expiresDate:2016-04-08 09:31:09 +0000 created:2016-04-08 09:30:49 +0000 sessionOnly:FALSE domain:"www.xsd.me" path:"/" isSecure:FALSE>

持久化到了文件中,地址是 沙盒的 /Library/Cookies/(app_Bundle_ID).binarycookies

2.app端手动存储Cookie

如果没设置Cookie失效时间expiresDate:(null),sessionOnly:true,kill掉后系统不会自动保存Cookie,如果想持久化Cookie 模仿浏览器存住Cookie,使用NSUserDefaults存下即可,以下是一条Cookie输出

<NSHTTPCookie version:0 name:"TestCookie" value:"my+cookie+value" expiresDate:(null) created:2016-04-08 09:33:34 +0000 sessionOnly:TRUE domain:"www.xsd.me" path:"/" isSecure:FALSE>

手动保存

//合适的时机保存Cookie
- (void)saveCookies{
    NSData *cookiesData = [NSKeyedArchiver archivedDataWithRootObject: [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject: cookiesData forKey: @"COOKIES"];
    [defaults synchronize];
}
//合适的时机加载Cookie 一般都是app刚刚启动的时候
- (void)loadCookies{
    NSArray *cookies = [NSKeyedUnarchiver unarchiveObjectWithData: [[NSUserDefaults standardUserDefaults] objectForKey: @"COOKIES"]];
    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    for (NSHTTPCookie *cookie in cookies){
        [cookieStorage setCookie: cookie];
    }
}
上一篇 iOS消除警告Mac上好用的抓包工具——Charles的使用教程 下一篇
评论 0
由于之前使用多说插件出现问题,导致以前的评论丢失,在此深表歉意!

站点统计

  • 建站日期:2014-12-06
  • 最后更新:2016-05-19
  • 运行时间:1351 天
  • 文章数量:46 篇