转载:天狐博客 » 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];
}
}
|