最近项目中用到了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会被清除