iOS的Cookie存取看我绝对够!!

作者: si1ence | 来源:发表于2016-06-29 15:27 被阅读14939次

    当前一些公司为了快速出一款app,很多时候采用UINavigationController+WebView或者NavigationController+UITabbarVC+WebView的方式,这样就不可避免的需要使用cookie与Html5交互,下面讲述几种常用情景下cookie的添加方法:

    一. UIWebView:

    // 工厂类中存储cookie的方法
    + (void)saveCookies {
        // 创建一个可变字典存放cookie
        NSMutableDictionary *fromappDict = [NSMutableDictionary dictionary];
        [fromappDict setObject:@"fromapp" forKey:NSHTTPCookieName];
        [fromappDict setObject:@"ios" forKey:NSHTTPCookieValue];
        // kDomain是公司app网址
        [fromappDict setObject:kDomain forKey:NSHTTPCookieDomain];
        [fromappDict setObject:kDomain forKey:NSHTTPCookieOriginURL];
        [fromappDict setObject:@"/" forKey:NSHTTPCookiePath];
        [fromappDict setObject:@"0" forKey:NSHTTPCookieVersion];
    
        // 将可变字典转化为cookie
        NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:fromappDict];
    
        // 获取cookieStorage
        NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]
     
        // 存储cookie
        [cookieStorage setCookie:cookie];
    }
    
    • UIWebView使用时间较长,只要在cookieStorage中设置了相应的cookie,每次就会自动带上;
    • 但是这样的弊端是随着与H5的交互增加,Cookie占用的空间越来越大,每次交互都夹带大量的cookie,不仅增加服务器端压力,也浪费用户的流量。比如每次交互都夹带5kb的cookie内容,但是真正用到的只有两三百字节。

    二. WKWebView

    • WKWebView相比于UIWebView:

      • 速度快了一倍,内存却减少为原来的一半;
      • cookie不再是自动携带,需要手动设置;
      • 交互更加顺畅,比如app底部四个tabBar也都是网页的,在UIWebView下点击,整个H5页面都会闪白一下,但是在WKWebView下点击,四个tabBar效果与原生app效果更加类似,不会有闪白现象。
      • 增减了一些代理方法,更方便的进行协议拦截和进度条展示
    • 1.在创建的时候存放到WKUserScript中进行添加cookie

        WKWebViewConfiguration *webConfig = [[WKWebViewConfiguration alloc] init];
        // 设置偏好设置
        webConfig.preferences = [[WKPreferences alloc] init];
        // 默认为0
        webConfig.preferences.minimumFontSize = 10;
        // 默认认为YES
        webConfig.preferences.javaScriptEnabled = YES;
        // 在iOS上默认为NO,表示不能自动通过窗口打开
        webConfig.preferences.javaScriptCanOpenWindowsAutomatically = NO;
    
        // web内容处理池
        webConfig.processPool = [[WKProcessPool alloc] init];
        // 将所有cookie以document.cookie = 'key=value';形式进行拼接
        #warning 然而这里的单引号一定要注意是英文的,不要问我为什么告诉你这个(手动微笑)
        NSString *cookieValue = @"document.cookie = 'fromapp=ios';document.cookie = 'channel=appstore';";
        
        // 加cookie给h5识别,表明在ios端打开该地址
        WKUserContentController* userContentController = WKUserContentController.new;
        WKUserScript * cookieScript = [[WKUserScript alloc]
                                       initWithSource: cookieValue
                                       injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
        [userContentController addUserScript:cookieScript];
        webConfig.userContentController = userContentController;
    
        WKWebView *wkWebView = [[WKWebView alloc] initWithFrame:frame configuration:webConfig];
    
        wkWebView.UIDelegate = wkWebView;
        wkWebView.navigationDelegate = wkWebView;
    
    • 2.加载某个url的时候添加cookie

    如果WKWebView在加载url的时候需要添加cookie,需要先手动获取当前NSHTTPCookieStorage中的所有cookie,然后将cookie放到NSMutableURLRequest请求头中

    - (void)loadRequestWithUrlString:(NSString *)urlString {
        
        // 在此处获取返回的cookie
        NSMutableDictionary *cookieDic = [NSMutableDictionary dictionary];
        
        NSMutableString *cookieValue = [NSMutableString stringWithFormat:@""];
        NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
        
        for (NSHTTPCookie *cookie in [cookieJar cookies]) {
            [cookieDic setObject:cookie.value forKey:cookie.name];
        }
        
        // cookie重复,先放到字典进行去重,再进行拼接
        for (NSString *key in cookieDic) {
            NSString *appendString = [NSString stringWithFormat:@"%@=%@;", key, [cookieDic valueForKey:key]];
            [cookieValue appendString:appendString];
        }
    
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
        [request addValue:cookieValue forHTTPHeaderField:@"Cookie"];
    
        [self loadRequest:request];
    }
    

    3.AFNetworking

    AFNetworking存取cookie就比较常见了,话不多说,都在代码里了

        // 获取AFHTTPRequestOperationManager
        AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
        
        // 创建可变字典用于存放Cookie
        NSMutableDictionary *cookieDic = [NSMutableDictionary dictionary];
        
        // 存放新添加的cookie
        #warning 单个的Cookie还好,但是楼主在工厂类方法中拼接了一个包含6个设备信息的value值,最后忘记加分号了,测试也没测出来
        #warning 因为不影响功能,但是后面的cookie就自动拼接上了,H5那边也识别不到,险造成重大事故(涉及金融。。),望后来者看到,提前做好准备(就凭这个坑,你得给我个赞)
        NSMutableString *cookieValue = [NSMutableString stringWithFormat:@"fromapp=ios;"];
    
        // 获取
        NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage];
        
        for (NSHTTPCookie *cookie in [cookieJar cookies]) {
            [cookieDic setObject:cookie.value forKey:cookie.name];
        }
        
        // cookie重复,先放到字典去重,再进行拼接
        for (NSString *key in cookieDic) {
            NSString *appendString = [NSString stringWithFormat:@"%@=%@;", key, [cookieDic valueForKey:key]];
            [cookieValue appendString:appendString];
        }
    
        // 将cookie存到请求头中
        [operationManager.requestSerializer setValue:cookieValue forHTTPHeaderField:@"Cookie"];
        
        //  拼接url地址
        NSString *urlStr = [NSString stringWithFormat:@"%@%@", kHostIP, kPath];
        
        // 设置参数字典
        NSDictionary *paraDict = @{
                                      @"key" : value
                                      };
        // 发送请求,处理结果
        [operationManager POST:urlStr parameters:paraDict success:^(AFHTTPRequestOperation * _Nonnull operation, id  _Nonnull responseObject) {
            
             NSLog(@"responseObject-->%@", responseObject);
            
        } failure:^(AFHTTPRequestOperation * _Nullable operation, NSError * _Nonnull error) {
    
             NSLog(@"error-->%@", error);
        }];
    

    相关文章

      网友评论

      • XiuFi:楼主,我有个问题。我用wkwebview塞cookie的时候。如果手机系统11.2以下,可以H5那边可以正常拿的到cookie值,但是11.3以上就没办法拿到cookie了,这个怎么破
      • 吴德馨:幸好有你的文章,不然我 wkwebview 上的网页事件都无法请求了
      • RY_zheng:楼主有没有自己手动管理cookie, 遇到过拦截重定向时,中间结果的response的cookies无法成功存到cookie storage的情况。
        踏遍青山:@蓝新 请问下是如何解决的?
        RY_zheng:@si1ence NSURLSession 已经找到办法解决了。
        si1ence:@蓝新 WK还是UI?
      • JupiAZ:楼主,你好,我现在需要在app登录成功之后服务器给我一个字段,是一个值,然后点进一个web里面的时候,成字登录状态,也就是免登录,这个cookie怎么设置么,多谢
        si1ence:@guojuzheng 塞进header里面不就ok了么
      • 爱阿爸的阿龙龙:最近刚接触到 并做了一些这方面的东西 希望和作者多多交流
      • Draven_Lu:楼主你好,很感谢你的分享.
        问题:1抓包+log怎么联调啊
        2我按照你说的方法都试过了,但是h5那边取不到我放进去的cookie 所以想定位下问题在哪里,但是找不到联调的方法.
        QQ:308619178
        si1ence:@Draven_Lu 用Charles 抓包看一下你放进去没有就ok了
      • 老牛不牛气:学习了
      • __下一个天亮__:楼主,请教一下:H5可以种下cookie 然后客户端获取cookie吗?不同的浏览器种下的cookie 客户端都可以收到吗?感谢!
        健健锅:@__下一个天亮__ wk 中应该是不好使的
        si1ence:@__下一个天亮__ 试一下不就知道了
        __下一个天亮__:还有一个问题 获取cookie的方法:NSHTTPCookieStorage *cookieJar = [NSHTTPCookieStorage sharedHTTPCookieStorage]; 可以用在appdelegate中didFinishLaunchingWithOptions 方法里面直接使用吗?
      • 4d6491442ca9:哥们,我这边有个需求就是在webview加载的网页里后台要在cookie里面取数据 但是拿不到 你怎么做的
        si1ence:@健健锅 读取的方式也写了啊
        健健锅:@si1ence 你里面写了春cookie,但是没有读取cookie .我也在找这个方法
        si1ence:@4d6491442ca9 晕,这篇文章不就是在这里面讲这些的么。。
      • 刘小弟:楼主,上传下code一下。
      • 多LV信源:楼主, 你好, 比较急, 我现在要获取cookie, 比如说, 成功登录某个网址后, 获取此时的cookie
        NSHTTPCookieStorage *sharedHTTPCookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
        NSArray *cookies = [sharedHTTPCookieStorage cookiesForURL:[NSURL URLWithString:successURL]];
        NSLog(@"这是cookies数组%@",cookies);

        if (cookies.count > 0) {
        NSEnumerator *enumerator = [cookies objectEnumerator];
        NSHTTPCookie *cookie;
        NSMutableString *mStr = [NSMutableString string];
        while (cookie = [enumerator nextObject]) {
        [mStr appendFormat:@"%@=%@;",[cookie name], [cookie value]];
        }
        [mStr deleteCharactersInRange:NSMakeRange(mStr.length - 1, 1)];
        NSLog(@"1这是cookie:%@", [mStr copy]);
        }
        为什么cookie,为空呢? 我这个cookie与楼主的添加cookie不一样, 楼主的是, 如果登录某个网页第二次, 把第一次的cookie拿到, 在线等, 急
        si1ence:@__下一个天亮__ 应该可以,不同浏览器的适配要看h5同学的技术了
        __下一个天亮__:楼主,请教一下:H5可以种下cookie 然后客户端获取cookie吗?不同的浏览器种下的cookie 客户端都可以收到吗?感谢!
        丶小杨_:请问cookie能获取到了吗
      • 703500b4eb0f:我用WKUserScript的方法添加的cookie~有些网页有效果有些没有是为什么?
        然后用[request addValue:cookieValue forHTTPHeaderField:@"Cookie"];的方法所有网页都没效果~
        si1ence:@摸摸看书 后者是UIWebView的添加方法,cookie有时候就是会丢。。可以用抓包+Log检测,看在哪一步出了问题
      • 0c9691c144d2:小伙子 不错,我决定跟你交朋友, /绿箭
        si1ence:@邹彦军 哈哈,以后多多交流技术
      • 天马流星权:同学,我要求教啊,我现在情况是这样的.我们在登录的时候,服务器反返回一个cookie携带一个登录验证的字符串,我现在要在用户启动app之后,把这个字符串发回给服务器来完成自动登录,,,UIWebView实现了,但是wkWebView不会做..返回的cookie的key是auth.....我怎么样才能在用户登录完成后,保存这个value,在发送请求的时候携带这个value呢,你的代码.我不明白 .....谢谢,,,, 上网找了不少方法都不行.....看着你的比较靠谱,但是不会做......
        天马流星权:@si1ence 对了,你的手动添加是什么意思,我不懂....我是一个新手...本来可以直接用UI就没事了...但是...就是不服...想搞定WK....
        天马流星权:@si1ence 是这样的,我用UI的时候,是可以收到有cookie.理论上,我用WK也会收到有cookie的呀?我认为,就是我获取不了而已.但是已经一天了.....搞不定....
        si1ence:@36edcb7769e7 你先抓包看一下有没有接收到这个cookie,有的话就获取过来添加上,没有的话再跟服务器联调一下,wk需要手动添加,UI是自动添加的
      • glView:WKWebview如何取cookie呢,这里是说了存
        glView:@si1ence NSHTTPCookieStorage这个吗?
        glView:@si1ence 劳烦,有代码没?
        si1ence:@0468059df06b 都是从cookieStoryge里面取
      • 孤独雪域:我想获取safari的cookie
        si1ence:@孤独雪域 safari支持9.0以上,现在一般都没用到。。过一段有时间研究下加上去
      • 偌上:wk没有单个url添加cookie的方法。不要误人啊
        丐帮头:赞同
      • Ryan文濤:小伙子,可以的。不错! :smile:
      • CoderDancer:很有收获
      • 智商癌晚期:很想问问WKUserScript 添加Cookie方法里面 #Warning 下面那句NSString 为什么要带中辍符?
        si1ence:@智商癌晚期 哎呀,不好意思,项目里面是拼接的Format,弄过来没删干净。。已修改
        智商癌晚期:@si1ence NSString *cookieValue = [@"document.cookie = 'fromapp=ios';document.cookie = 'channel=appstore';"]; 这一句,为什么要加 [ ];
        si1ence:@智商癌晚期 什么是中辍符?
      • Sam宋:给你点赞
      • Eric_1024:挺好...
      • 罗同学_:之前就是因为没找到wk添加cookie的方法就放弃使用了 :joy:
        牵线小丑: :joy: WKWebView的坑真是不少呀,目前项目就遇到了不少呀……都花了不少时间才找到问题……
        智商癌晚期:@si1ence 我也是,一直没找到添加cookie的方法。 谢谢楼主
        si1ence:@单手两万行无bug WKWebView的坑掠夺,用这个只能是程序员自己感动了自己
      • d94098065219:可以的,小伙子

      本文标题:iOS的Cookie存取看我绝对够!!

      本文链接:https://www.haomeiwen.com/subject/uwdedttx.html