欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

一篇文章搞定iOS的Cookie存取

程序员文章站 2023-12-17 15:48:28
cookie简介 cookie是在客户端存储服务器状态的一种机制,web服务器可以通过set-cookie或者set-cookie2 http头部设置cookie。...

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);
 }];

总结

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

上一篇:

下一篇: