IOS 中Cookie简介与操作

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存储中取出来

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容