轉載:天狐博客 » ios
htttp網絡請求cookie的讀取與寫入(NSHTTPCookieStorage)
當你訪問一個網站時,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 htttp網絡請求cookie的讀取與寫入:
1.原生NSURLConnection寫法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | 一.獲取cookie - (IBAction)cookieTouched:(id)sender { NSURL *url = [NSURL URLWithString:@"http://api.skyfox.org/api-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 寫法
1
2
3
4
5
6
7
8
9
10
11
12
|
[[APIClient
sharedClient]
postPath:@"http://api.skyfox.org/api-test.php"
parameters:p
success:^(AFHTTPRequestOperation
*operation,
id
JSON)
{
NSDictionary
*fields
=
[operation.response
allHeaderFields];
//afnetworking寫法
NSLog(@"fields
= %@",[fields
description]);
NSURL
*url
=
[NSURL
URLWithString:@"http://api.skyfox.org/api-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不會自動持久化到沙盒
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
第一次請求手動設置個cookie
-(void)test1:(NSString*)urlString{
NSURL
*url
=
[NSURL
URLWithString:@"http://api.skyfox.org/cookie.php"];
NSMutableURLRequest
*request
=
[NSMutableURLRequest
requestWithURL:url];
NSMutableDictionary
*cookieProperties
=
[NSMutableDictionary
dictionary];
[cookieProperties
setObject:@"username"
forKey:NSHTTPCookieName];
[cookieProperties
setObject:@"my
ios cookie" forKey:NSHTTPCookieValue];
[cookieProperties
setObject:@"api.skyfox.org"
forKey:NSHTTPCookieDomain];
[cookieProperties
setObject:@"api.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://api.skyfox.org/cookie.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:"api.skyfox.org"
path:"/"
isSecure:FALSE>
|
持久化到了文件中,地址是 沙盒的 /Library/Cookies/org.skyfox.AFNetworking-demo.binarycookies
使用BinaryCookieReader.py腳本 解析 org.skyfox.AFNetworking-demo.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:"api.skyfox.org" path:"/" isSecure:FALSE> |
手動保存
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
//合適的時機保存Cookie
-
(void)saveCookies{
NSData
*cookiesData
=
[NSKeyedArchiver
archivedDataWithRootObject:
[[NSHTTPCookieStorage
sharedHTTPCookieStorage]
cookies]];
NSUserDefaults
*defaults
=
[NSUserDefaults
standardUserDefaults];
[defaults
setObject: cookiesData
forKey:
@"org.skyfox.cookie"];
[defaults
synchronize];
}
//合適的時機加載Cookie 一般都是app剛剛啓動的時候
-
(void)loadCookies{
NSArray
*cookies
=
[NSKeyedUnarchiver
unarchiveObjectWithData:
[[NSUserDefaults
standardUserDefaults]
objectForKey:
@"org.skyfox.cookie"]];
NSHTTPCookieStorage
*cookieStorage
=
[NSHTTPCookieStorage
sharedHTTPCookieStorage];
for
(NSHTTPCookie
*cookie
in
cookies){
[cookieStorage
setCookie: cookie];
}
}
|