Cookie向服务器提供了追踪会话状态能力,Cookie的值由服务器通过请求提供,然后被放到随后的请求中。Cookie基本上几十到几百个字节
IOS 中Cookie类为 NSHTTPCookie
常见Cookie属性
name - Cookie 的名字, 从同一 DNS 域返回的所有 Cookie 名都是唯一的. 只有 name 和 value 这两个属性才会在后续的请求中发送给服务器.
value - 由向服务器发送的下一请求返回的值
domain - 后续请求在 Cookie 中包含的 DNS 域. 比如, 拥有域值.domain1.col 的 Cookie 不应该返回给.domain2.com . 如果省略掉, 那么客户端就会将 URL 的主机名当作域. 如果域的最前面是个圆点(.), 那么 Cookie 就会返回给发送到该域及其子域的任何请求. 如果没有最前面的圆点, 那么 Cookie 就只会包含在发送给该域而非其子域的请求中.
path - path 限制发送给请求的 Cookie 都是针对指定的 URL 路径. 如果与 DNS 域搭配使用, 那么 path 属性就可以限制只会将 Cookie 发送给服务器上有限且精确的 URL 集合.
Expiration Date - Cookie 不再随请求发送的日期与时间, Cookie 会在这个时间点从客户端存储中删除
Session Only - 指定 Cookie 是在当前浏览器会话时间内返回还是一直持续到过期日期, 以二者之间先到的时间为准. 在 iOS 应用中, 会话指的是 OS 加载应用到终止应用之间的应用生命周期.
Secure - 指定 Cookie 只会用在 HTTPS 连接而非 HTTP 连接上
Comment - 用于向用户说明 Cookie 目的的注释值
Comment URL - URL 值, 向用户提供了一个 HTML 文档, 用于说明 Cookie 的目的
HTTP Only - 指示器, 告诉客户端不要与 JavaScript 应用共享 Cookie 以防止跨站脚本攻击
Version - Cookie 遵循的 HTTP Cookie 规范版本
URL 加载系统会自动处理HTTP与HTTPS 请求的Cookie。会将返回的Cookie保持在响应中,然后按照Cookie处理规则将其添加到随后的请求中。
URL 加载系统提供NSHTTPCookieStorage 管理Cookie,该对象为单例,与所有其他的应用数据一样, NSHTTPCookieStorage Cookie也是沙箱的, 无法在应用间共享。
NSHTTPCookieStorage 默认会存储响应中返回的所有Cookie,无论Cookie的域是否匹配请求的域,可以通过修改Cookie接受策略进行更改
/*!
@method cookieAcceptPolicy
@abstract The cookie accept policy preference of the
receiver.
*/
@property NSHTTPCookieAcceptPolicy cookieAcceptPolicy;
NSHTTPCookieAcceptPolicyAlways - 这是默认值, 表示任何返回的 Cookie 都应该被保存下来
NSHTTPCookieAcceptPolicyNever - 这个值表示不应该存储 Cookie
NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain - 该策略告诉 NSHTTPCookieStorage 对象只保存域值与请求域相匹配的 Cookie
一、从响应中获取Cookie
NSHTTPURLResponse 中含有allHeaderFields 属性,该属性含有HTTP返回头部信息,从中提取Cookie
/*!
@method allHeaderFields
@abstract Returns a dictionary containing all the HTTP header fields
of the receiver.
@discussion By examining this header dictionary, clients can see
the "raw" header information which was reported to the protocol
implementation by the HTTP server. This may be of use to
sophisticated or special-purpose HTTP clients.
@result A dictionary containing all the HTTP header fields of the
receiver.
*/
@property (readonly, copy) NSDictionary *allHeaderFields;
NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url];
NSHTTPURLResponse *response;
NSError *error;
[NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
NSDictionary *heades = [response allHeaderFields];
NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:heades forURL:url];
for (NSHTTPCookie *cookie in cookies) {
NSLog(@"%@%@\n", cookie.name, cookie.value);
}
删除Cookie
操作应用中存储的cookie, 删除所有Cookie
- (void)deleteAllCookies{
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray *cookies = [cookieStorage cookies];
for (NSHTTPCookie *cookie in cookies) {
[cookieStorage deleteCookie:cookie];
}
[[NSUserDefaults standardUserDefaults] synchronize];
}
可以组合使用Cookie属性,针对特定Url,删除Cookie
/*!
@method cookiesForURL:
@abstract Returns an array of cookies to send to the given URL.
@param URL The URL for which to get cookies.
@result an NSArray of NSHTTPCookie objects.
@discussion The cookie manager examines the cookies it stores and
includes those which should be sent to the given URL. You can use
<tt>+[NSCookie requestHeaderFieldsWithCookies:]</tt> to turn this array
into a set of header fields to add to a request.
*/
- (nullable NSArray<NSHTTPCookie *> *)cookiesForURL:(NSURL *)URL;
- (void)deleteCookie:(NSString *)cookieName url:(NSURL *)url{
NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSArray *storedCookies = [cookieStorage cookiesForURL:url];
for (NSHTTPCookie *cookie in storedCookies) {
if ([cookie.name isEqualToString:cookieName]) {
[cookieStorage deleteCookie:cookie];
}
}
[[NSUserDefaults standardUserDefaults] synchronize];
}
创建Cookie
手动创建Cookie并通过编程的方式添加到请求或Cookie存储中
1.添加到请求中
NSHTTPURLResponse *response = nil;
NSError *error = nil;
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:60 * 60 * 24 * 7];
NSHTTPCookie *cookie163 = [NSHTTPCookie cookieWithProperties:@{ NSHTTPCookieName : @"NTES_SESS", //NTES_SESS NTES_TRIP163
NSHTTPCookieValue : @"cookieValue",
NSHTTPCookieDomain : @".163.com",
NSHTTPCookiePath : @"/",
NSHTTPCookieExpires : date }];
NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://www.163.com"]];
NSArray *cookieArray = [NSArray arrayWithObject:cookie163];
NSDictionary *newHeaders = [NSHTTPCookie requestHeaderFieldsWithCookies:cookieArray];
[req setAllHTTPHeaderFields:newHeaders];
[NSURLConnection sendSynchronousRequest:req returningResponse:&response error:&error];
通过设置HTTP请求头信息,会将包含Cookie信息的新头替换掉默认的头内容。如果代码中需要添加其他头信息,需要在调用setAllHttpHeaderFields:之前将其添加到字典中。
2、Cookie存储到本地方式
NSDate *date = [NSDate dateWithTimeIntervalSinceNow:60 * 60 * 24 * 7];
NSHTTPCookie *cookie163 = [NSHTTPCookie cookieWithProperties:@{ NSHTTPCookieName : @"NTES_SESS", //NTES_SESS NTES_TRIP163
NSHTTPCookieValue : @"cookieValue",
NSHTTPCookieDomain : @".163.com",
NSHTTPCookiePath : @"/",
NSHTTPCookieExpires : date }];
[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie163];
[[NSUserDefaults standardUserDefaults] synchronize];
存储完成后,再新的请求执行时,会自动将其从Cookie存储中取出来
网友评论