最近项目中用到了webView加载服务器返回的链接,因为没有cookie而发生错误的情况。发现项目组小弟对cookie不是很了解,特地在这边文章中对cookiede常用的操作进行一个小的总结。

其实当你在访问一个网站的时候,NSURLRequest会主动帮你记下来你访问的站点设置的cookie,而在你下次访问的时候,NSURlRequest会拿着你的cookie继续请求.下面是对cookie集中常用的操作:

1、获取cookie:

NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
for (NSHTTPCookie *cookie in [cookieJar cookies]) {
   NSLog(@"%@", cookie);
}

示例:

<NSHTTPCookie version:0 name:"PHPSESSID" value:"evf5rcboo8th1dnl53fs4ukmt2" expiresDate:(null) created:2012-03-13 14:28:13 +0000 (3.53342e+08) sessionOnly:TRUE domain:"blog.cnrainbird.com" path:"/" isSecure:FALSE>

2、如果当前cookie为空,只要重新请求一个url

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://blog.cnrainbird.com"]
                                           cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData 
                                       timeoutInterval:3];

  [NSURLConnection sendSynchronousRequest:request 
                        returningResponse:nil
                                    error:nil];

  NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
  for (NSHTTPCookie *cookie in [cookieJar cookies]) {
    NSLog(@"%@", cookie);
  }

3、清空cookie

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

4、设置指定的cookie

NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];
  [cookieProperties setObject:@"username" forKey:NSHTTPCookieName];
  [cookieProperties setObject:@"rainbird" forKey:NSHTTPCookieValue];
  [cookieProperties setObject:@"cnrainbird.com" forKey:NSHTTPCookieDomain];
  [cookieProperties setObject:@"cnrainbird.com" forKey:NSHTTPCookieOriginURL];
  [cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
  [cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];

  NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];
  [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
在设置特定的cookis时,需要注意以下:
 (1):在NSDictionary设置字典的时候必须包含以下几项:NSHTTPCookieValue, NSHTTPCookieName, NSHTTPCookiePath, NSHTTPCookieDomain。
 (2):在甚至键值对NSHTTPCookiePath时,value必须是url的Domain。

5、AFNetworking读取和设置cookie的解决方案

实际上AFNetworking中并没有专门针对cookie封装的代码,但是由于它底层使用的是NSURLRequest,所以可以通过NSHTTPCookieStorage来操作cookie,读取和保存cookie的代码如下:
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookiesForURL: [NSURL URLWithString:kServerAddress]];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:cookies];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:kUserDefaultsCookie];
NSData *cookiesdata = [[NSUserDefaults standardUserDefaults] objectForKey:kUserDefaultsCookie];
if([cookiesdata length]) {
    NSArray *cookies = [NSKeyedUnarchiver unarchiveObjectWithData:cookiesdata];
    NSHTTPCookie *cookie;
    for (cookie in cookies) {
        [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
    }
}
注意如下两点:
(1) 通过以上方法保存cookie,即可实现在退出程序,下一次进入的时候不用登录而再次使用cookie
(2) 通过以上方法设置的cookie,通过webview的loadRequest方法load NSURLRequest时可以共用cookie。

6、某种特定的情况:UIWebView访问网站时,经常遇到的一个问题是需要登录。比如访问新浪微博,或者访问某个个人账号,但是需要直接访问服务器返回的某个url,却会被重定向到登录页进行登录。

那么真正的浏览器是如何做到的直接登录?一般来说,答案都是cookies。在你第一次登录时,网站设置了cookie,浏览器保存这些携带了登录信息的cookies,以后就可以直接登录。

    所以我们要做的就是在url request中带上cookies。NSMutableURLRequest中提供了- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field 方法。可以用来设置Http request header中的各个属性。

以今天项目终于到的需要传递userid和token为例:

NSDictionary *dictCookieUId = [NSDictionarydictionaryWithObjectsAndKeys:
@"userId", NSHTTPCookieName,  
userId, NSHTTPCookieValue,
@"/",NSHTTPCookiePath,
@"test.com",NSHTTPCookieDomain,nil];

    NSHTTPCookie *cookieUserId = [NSHTTPCookie cookieWithProperties:dictCookieUId];

//set token to cookie
    NSDictionary *dictCookiePToken = [NSDictionarydictionaryWithObjectsAndKeys:
@"token", NSHTTPCookieName,
token, NSHTTPCookieValue,
@"/", NSHTTPCookiePath,
@"test.com, NSHTTPCookieDomain, nil];

    NSHTTPCookie *cookiePassToken = [NSHTTPCookie cookieWithProperties:dictCookiePToken];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURLURLWithString:strUrl]];

    // set cookies
    NSArray *arrCookies = [NSArray arrayWithObjects: cookieUserId, cookiePassToken, nil];


    for (NSHTTPCookie *cookie in cookiesForDomain) {
        NSString *cookieString = [NSString stringWithFormat:@"%@=%@", [cookie name], [cookie value]];
        [newRequest setValue:cookieString forHTTPHeaderField:@"Cookie"];
        NSLog(@"inserted cookie into request: %@", cookie);
    }
    [self.webView loadRequest:newRequest];

7、其他。

(1)简单说不管是NSURLConnection还是UIWebView都会保留并传递服务端的cookie,重启进程,或重启系统cookie都在应用中。
(2)多个应用间默认是不共亨cookie的
(3)删除重装应用cookie会被清除