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的读取与写入:

Cookie必然会通过HTTP的Respone传过来,并且Cookie在Respone中的HTTP header中。不管是什么请求框架,必然会存在Respone对象,比如AFNetworking2.x的operation.response,AFNetworking3.x的task.response等等。。。。

1.原生NSURLConnection写法

一.获取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 写法

[[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不会自动持久化到沙盒

第一次请求手动设置个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的本地缓存策略

//NSHTTPCookieAcceptPolicyAlways:保存所有cookie,这个是默认值
//NSHTTPCookieAcceptPolicyNever:不保存任何响应头中的cookie
//NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain:只保存域请求匹配的cookie

[[NSHTTPCookieStorage sharedHTTPCookieStorage]setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyNever];

五.Cookie的持久化存储

1.服务器端设置Cookie,以PHP为例

语法

1

setcookie(name,value,expire,path,domain,secure)

参数 描述
name 必需。规定 cookie 的名称。
value 必需。规定 cookie 的值。
expire 可选。规定 cookie 的有效期。
path 可选。规定 cookie 的服务器路径。
domain 可选。规定 cookie 的域名。
secure 可选。规定是否通过安全的 HTTPS 连接来传输 cookie。

1

2

3

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输出

1

<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输出

1

<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>

手动保存

//合适的时机保存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];
    }
}

原文地址:https://www.cnblogs.com/somebodywx/p/8929609.html

时间: 2024-08-07 16:37:14

iOS htttp网络请求cookie的读取与写入(NSHTTPCookieStorage)的相关文章

iOS HTTP网络请求Cookie的读取与写入(NSHTTPCookieStorage)

当你访问一个网站时,NSURLRequest都会帮你主动记录下来你访问的站点设置的Cookie,如果 Cookie 存在的话,会把这些信息放在 NSHTTPCookieStorage 容器中共享,当你下次再访问这个站点时,NSURLRequest会拿着上次保存下来了的Cookie继续去请求.同样适用于ASIHTTPRequest,AFNetworking, Webview等,Cookie常用于一些基于认证的网络请求 认识下NSHTTPCookieStorageNSHTTPCookieStorag

iOS开发WKWebView Cookie的读取与写入,与UIWebView的Cookie共享

NSHTTPCookieStorage和NSHttpCookie NSHTTPCookieStorage 实现了一个管理Cookie的单例对象(只有一个实例),每个Cookie都是NSHTTPCookie类的实例,做为一个规则,Cookie在所有应用 之间共享并在不同进程之间保持同步.Session Cookie(一个isSessionOnly方法返回YES的Cookie)只能在单一进程中使用. UIWebView Cookie 同一个应用,不同UIWebView之间的Cookie是自动同步的.

iOS开发网络请求——大文件的多线程断点下载

iOS开发中网络请求技术已经是移动app必备技术,而网络中文件传输就是其中重点了.网络文件传输对移动客户端而言主要分为文件的上传和下载.作为开发者从技术角度会将文件分为小文件和大文件.小文件因为文件大小比较小导致传输所需时间少传输就快,因此不太容易影响用户体验,可用的技术就多.而大文件因为文件大小比较大导致传输时间长,因此就需要考虑到各种用户体验,比如避免在上传下载文件过程中阻塞主线程影响用户体验,就需要使用到多线程技术:为了给用户友好的进度提示,因此又需要开发中跟踪数据上传和下载数据的变化:为

iOS中网络请求的使用(GET请求与POST请求)

GET&POST GET和POST是两种最常用的与服务器进行交互的HTTP方法 GET 语意是获取指定URL的资源. 将数据按照variable=value的形式,添加到action所指向的URL后面,并且两者只用“?”连接,各变量之间使用“&”连接. 貌似不安全,因为在传输过程中,数据被放在请求的URL中. 传输的数据量小,这主要是因为受URL长度限制. POST POST的语意说向指定URL的资源添加数据. 将数据放在数据体中,按照变量和值相对应的方式,传递到action所指向URL.

iOS开发——网络请求方法汇总

在实际的项目开发中,连接网络是每一款App必不可少的基本功能.对于客户端的网络请求而言,无非是有两个实现方向:使用网络请求框架或者不使用网络请求框架.在这篇博客中,我将用苹果自带的网络请求方式(不使用第三方框架)下对iOS网络请求方法做一个汇总.我将在之后的博客中介绍使用AFNetworking框架进行请求的实现.代码已经上传至:https://github.com/chenyufeng1991/iOS-NetworkRequest   . [使用XML请求Webservice,可用GET或PO

iOS之网络请求

iOS中遵循较为安全的HTTPS安全超文本协议,若想访问遵循HTTP协议的网页需要进行以下设置: 将代码<key>NSAppTransportSecurity</key>     <dict>        <key>NSAllowsArbitraryLoads</key>             <true/>    </dict> 复制到 路径下: 或者在info.plist文件中添加以下字段 请求方式分为GET和PO

【iOS】网络请求框架封装

在使用网络请求的过程中,可以使用系统的框架.ASI.AF.MK等等,但是如果需要更换项目的网络请求框架(比如,项目之前用的ASI的框架,现在需要更换为AF),那么这将是一个浩大的工程.项目初期,怎么搭建网络请求框架,才可以让修改网络请求的工程量减到最小呢,这是我们今天要说的问题. 环境信息: Mac OS X 10.10.1 Xcode 6.1.1 iOS 8.1 正文 封装的网络请求框架一共三层: 第三层:ASI.AF或者其他网络请求方式.第二层:第二层分有基类与类目(Category)构成,

iOS封装网络请求

iOS中经常会有网络请求,可以把它封装起来,方便使用: 网络封装请求类: .h文件: #import <Foundation/Foundation.h> @interface NetHandler : NSObject //无返回值,根据网络请求 的特点,不同的地方就是请求的地址和分析数据的方式不一样,就是把这两部分分别作为方法参数 + (void)getDataWithUrl:(NSString *)str complietion:(void(^)(NSData *data))block;

iOS进阶(网络请求)

1.网络请求方式 GET:通过网址字符串  网址字符串最多255字节  所有传输给服务器的数据都显示在网址里,直接可见,不安全 POST:通过data  容量很大 数据被转换成二进制数 安全 2.连接方式 同步连接:程序容易出现卡死现象 异步连接:等待数据返回 (有代理和block两种方式)创建请求对象时,采用NSMutableURLRequest对象并设置请求方式和body主体 POSTBlock异步block //创建一个NSURLSession对象 NSURLSession *sessio