天天看點

iOS中Cookie介紹 轉載:http://www.winddisk.com/2013/02/05/ios中cookie介紹/

轉載:http://www.winddisk.com/2013/02/05/ios中cookie介紹/

參考:http://blog.cnrainbird.com/index.php/2012/03/13/ios_zhong_http_shi_yong_cookie/

一. 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。

有關Cookie的詳細内容請參考《HTTP權威指南》的相關章節。

二. NSHTTPCookie

在iOS中使用NSHTTPCookie類封裝一條cookie,通過NSHTTPCookie的方法讀取到cookie的通用屬性。

- (NSUInteger)version;
- (NSString *)name;
- (NSString *)value;
- (NSString *)domain;
- (NSString *)path;
- (BOOL)isSessionOnly;
等
           

可以通過手工指派的方式建立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)接收到系統中。

三.NSHTTPCookieStorage

NSHTTPCookieStorage單件類提供了管理所有NSHTTPCookie對象的接口,在OS X裡,cookie是在所有程式中共享的,而在iOS中,cookie隻當目前應用中有效。

通過sharedHTTPCookieStorage方法可擷取到共享的NSHTTPCookieStorage單件對象。

+ (NSHTTPCookieStorage *)sharedHTTPCookieStorage;

使用NSHTTPCookieStorage單件對象可擷取到目前存儲的所有cookie

- (NSArray *)cookies

或針對特定URL的cookie

- (NSArray *)cookiesForURL:(NSURL *)theURL;

還可以添加/删除Cookie

– deleteCookie:

– setCookie:

– setCookies:forURL:mainDocumentURL:

通過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的http請求這塊很簡單應該不支援記錄,儲存,或者使用cookie,可是想當然歸想當然,真用的時候,真研究了一下發現還真強大。經過一番的研究簡單說一下我的了解:當你通路一個網站時,不管你願意或者不願意,NSURLRequest都會幫你主動記錄下來你通路的站點設定的cookie,而且很負責任的,當你下次再通路這個站點時,NSURLRequest會拿着上次儲存下來了的cookie繼續去請求。這規律同樣适用于ASIHTTPRequest。是以當你做一些基于認證的網絡請求時,cookie不失為一個完美的解決方案。那麼怎麼檢視cookie呢?很簡單:

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

這樣就列出了所有已儲存的cookie,如果目前為空怎麼辦呢?随便請求一個url喽。

NSURLRequest*request = [NSURLRequest requestWithURL:[NSURLURLWithString:@"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);
  }
           

是不是得到了類似:

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

的東東?這就是cookie啦

怎麼清空cookie呢?

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

這樣cookie就消失的一幹二淨了。

會檢視cookie了,也會清空cookie了,怎麼設定指定的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];
           

這樣就可以了。輸入一下,是不是得到了下面這樣的結果:

<NSHTTPCookieversion:0 name:"username" value:"rainbird"expiresDate:(null) created:2012-03-13 14:36:53 +0000 (3.53342e+08)sessionOnly:TRUE domain:"cnrainbird.com" path:"/"isSecure:FALSE>
           

其實ios的cookie就這麼簡單。如果mac也支援這麼幹的話,那以後寫點登陸的腳本不是簡單多了:)

參考:

NSHTTPCookieStorage Class Reference

NSHTTPCookie Class Reference

URL Loading System Programming Guide – Cookie Storage