当前位置: 移动技术网 > 移动技术>移动开发>IOS > 一篇文章搞定iOS的Cookie存取

一篇文章搞定iOS的Cookie存取

2019年07月24日  | 移动技术网移动技术  | 我要评论

cookie简介

cookie是在客户端存储服务器状态的一种机制,web服务器可以通过set-cookie或者set-cookie2 http头部设置cookie。

cookie可以分为两类,会话cookie和持久cookie,会话cookie是临时cookie,当前会话结束(浏览器退出)时cookie会被删除。持久cookie会存储在用户的硬盘上,浏览器退出,然后重新启动后cookie仍然存在。会话cookie和持久cookie的区别在于过期时间,如果设置了discard参数(cookie 版本1)或者没有设置expires(cookie版本0)或max-age(cookie版本1)设置过期时间,则此cookie为会话cookie

cookie有两个版本,一个是版本0(netscape cookies)和版本1(rfc 2965),目前大多数服务器使用的cookie 0。

有关cookie的详细内容请参考《http权威指南》的相关章节。

引言

当前一些公司为了快速出一款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);
 }];

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对移动技术网的支持。

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网